Issues in DataGrid With NewItemPlaceHolder and cancelled edit commits

Jan 12, 2009 at 2:22 AM
I wanted to let you know that there are some issues with the DataGrid canceled edits and NewItemPlaceHolders.
If a BeginningEdit event handler cancels the edit (by setting DataGridBeginningEditEventArgs.Cancel to true) , the control will correctly remove the new item it added to the ItemSource and then un-collapse the NewItemPlaceHolder row.

It does this by calling the private method  DataGrid.CancelRowItem().

The RowEditEnding event, however, does not remove the new row when a call to RowEditEnding sets Cancel to rue.
This can cause some problems.
To see why, consider the following sequence of events:

  1. The user starts editing the NewItemPlaceHolder row
  2. The control hides the new item place holder row, adds a new item to the control's item source, adds a new row to the grid for the new item, hides the NewItemPlaceHolder row, and transfers the selection state from the NewItemPlaceHolder to the new row
  3. The user does some editing, and then clicks on a new row in the grid
  4. The control fires a RowEditEnding event
  5. A handler for the RowEditEnding event sets DataGridRowEditEndingEventArgs.Cancel to true
  6. Because Cancel is set to true, the row is not committed
  7. Focus is then set to the new grid row
This ends up leaving the control in a messed up state.

The NewItemPlaceHolder row is still hidden, preventing the user from adding any more new rows.

The next time the "new" row is edited, because it's not the NewItemPlaceHolder row, the control acts as if it was editing an existing row, not a new one.
The end result is that the user can no longer edit any new rows. That is obviously a bug.

For me, I have a grid configured to automatically edit on click, using one of the samples from the "Tips and Tricks" session.
This mostly gives me the behavior that I want. A side effect of configuring things this way, when combined with this bug, is that the user clicking on the place holder row,
and then clicking somewhere else, ends up adding a new row to the grid, which clearly was not when the user intended to happen (if they wanted a new row, they would have entered in some values into the grid).

I can detect this (all the data in the row will have default values), and cancel the add.
This bug prevents me from doing that.

So, I hacked up the source code for the grid to enable this.

In my local copy of the source, I made 2 changes:
  1. I updated OnExecutedCommitEdit to call CancelRowItem() when both IsAddingNewItem() and rowEditEndingEventArgs.Cancel are true
  2. I changed OnEnterKeyDown() to not increment the current row if the current row ends up being the NewItemPlaceHolder row.
Now, these edits seem to be OK to me.

However, I don't know the source for the DataGrid very well. I only spent in total about an hour looking at the code and making the change, so I wanted to make sure that there isn't something major that I'm missing.

Does any one know if there are any scenarios where my hacky edits will screw stuff up?