But first a little bit about the workings of the DataGrid.
When binding data in a WPF DataGrid it holds all changes to the data in an intermediary object. If the user edits a cell the changes will be done only in this intermediary object, the exception being if the bound object does implement IEditableObject in which case the DataGrid uses the object's edit capabilities instead.
But if we do not have an IEditableObject to bind to all changes made inside the row will only be committed to the bound object once the row edit ends. If we still need to commit on a cell by cell basis we need to attach a handler to the CellEditEnding event of the grid and use the following code in the handler.
private bool isManualEditCommit; private void HandleMainDataGridCellEditEnding( object sender, DataGridCellEditEndingEventArgs e) { if (!isManualEditCommit) { isManualEditCommit = true; DataGrid grid = (DataGrid)sender; grid.CommitEdit(DataGridEditingUnit.Row, true); isManualEditCommit = false; } }
This will update the bound object whenever a cell edit is ending, i.e. whenever the cell looses focus.
15 comments:
Thanks very much for posting. I'm using the code in a Window to display an editable matrix. The user edits any cells before closing. Therefore you code is also called from Window closing.
Private isManualEditCommit As Boolean
Private Sub MainWindow_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles Me.Closing
CommitEdit()
MsgBox(dt.Rows(0)("Column1") & " " & dt.Rows(0)("Column2"))
End Sub
Private Sub DataGrid1_CellEditEnding(ByVal sender As Object, ByVal e As System.Windows.Controls.DataGridCellEditEndingEventArgs) Handles DataGrid1.CellEditEnding
CommitEdit()
End Sub
Sub CommitEdit()
If Not isManualEditCommit Then
isManualEditCommit = True
DataGrid1.CommitEdit(DataGridEditingUnit.Row, True)
isManualEditCommit = False
End If
End Sub
You also should only commit when e.EditAction is DataGridEditAction.Commit, otherwise pressing Cancel will not undo the current change.
Thanks a whole bunch ! I been struggling with the issue for the past few days. Your solution together with Christopher's is a great help to me.
perfect! thanks
This is beautiful. Using this allowed me to easily get a reference to actual datarows and make additional updates to the values, without having to do some really messy "ItemContainerGenerator.ContainerFromIndex(e.Row.GetIndex)" stuff. Thank you!
Hi, you write [...] if the bound object does implement IEditableObject in which case the DataGrid uses the object's edit capabilities [...].
I've collection of objects implementing IEditableObject, but DataGrid still using "per-row edit" and I don't see changes immediately. What I have to do to use IEditableObject capabilities? Where (in the code) DataGrid (or CollectionView) check and decide to use intermediary object instead of IEditableObject?
GREAT!!!
THX
Need to call "Keyboard.ClearFocus()" at the end. Otherwise very good
hi,
after celleditendingevent, i want to set the focus on the next cell of the selected row, do u have suggestion for this problem.
Thank you for your article. I'm using this handler with the CellEditEnding="HandleMainDataGridCellEditEnding" of my WPF DataGrid.
I'm also setting TAB and SHIFT+TAB functionality to my grid, in the GridView_PreviewKeyDown.
When pressing the TAB, I'm moving focus to the NEXT cell, and when pressing the SHIFT+TAB I'm moving focus to the PREVIOUS cell.
I have an event handler with each grid-cell, where each cell is of type TextBox. This handler is called TextBox_PreviewLostFocus.
When using TAB, the functionality is as expected (i.e. HandleMainDataGridCellEditEnding is executed after TextBox_PreviewLostFocus).
However when pressing SHIFT+TAB, "HandleMainDataGridCellEditEnding" is not being executed after TextBox_PreviewLostFocus.
Does your handler need to be called from any other specific place, since on SHIFT+TAB, CellEditEnding is not called.
Thanks.
What if focus is still exist in the respective cell which is a text box?
Thanks, it resolved my problem.
Thanks tou saved me ! I upgraded from wpf Toolkit DataGrid to 4.X DataGrid and didn't understand why propertychanged was not issued on selecting a cell on same row ;-)
Godd job Bro'!
Thanks a lot dude cheers
This is a easy way:
private void MenuItem_PreviewMouseMove(object sender, MouseEventArgs e)
{
Grid.CommitEdit();
}
Post a Comment