Hi, I'm trying to change the XamDataGrid's behavior, but I can't seem to get it working the way I want it to. The requirement is that, when a user is editing a row, the user should not be able to leave the row while it is invalid (and so it should stay in edit mode). However, the user should still be able to switch between cells because sometimes an object's validation state is determined by multiple properties (e.g. the From and Till properties in the sample).
The data object implements IDataErrorInfo and IEditableObject in order to support these functionalities.
Can you get my attached sample project working with these requirements?
Please take a look at Readme.txt, which is part of the Visual Studio solution. It contains more detailed technical information.
One more side question; when I set the wrong value for Icon (Red), and then press ESCAPE to roll back, I see some binding errors about PreDropDownAreaTemplate and PostDropDownAreaTemplate in the Visual Studio output window. Why is this?
Kind regards, Stefan
Hello Stefan,
Thank you for contacting Infragistics. I have been looking into your requirement and I managed to achieve it by handling to events of the XamDataGrid: ‘EditModeEnding’ and ‘XamDataGrid_RecordDeactivating’. In the first one I am getting the latest edited cell in the XamDataGrid and after that canceling the deactivating of a particular record if there is not acceptable data :
private void XamDataGrid_EditModeEnding(object sender, EditModeEndingEventArgs e)
{
activeCell = e.Cell;
}
private void XamDataGrid_RecordDeactivating(object sender, RecordDeactivatingEventArgs e)
if ((e.Record as DataRecord).DataError != null)
e.Cancel = true;
this.dataGrid1.ActiveCell = activeCell;
this.dataGrid1.ExecuteCommand(DataPresenterCommands.StartEditMode);
I am attaching a modified version of your sample application(EditableObjects2.zip) that shows my approach.
Let me know, if you need any further assistance on this matter.
Hey Yanko,
Thanks for helping! Your approach does indeed handle the record edit mode, but by solving it this way the IEditableObject functionality is broken. The EndEdit is called even when incorrect values are entered, so this means there is no more possibility to roll back these values.
There are 2 more requirements that I didn't mention before because I already got them working myself, which are now no longer working. (1) The user must be able to cancel the row editing, putting back the original values. This is the IEditableObject functionality I mentioned before. And (2) when the row is committed and the data object is valid, the row will be saved. You commented out the part that simulates the save functionality, but I believe that this requirement still works. If I uncomment the save-code it still seems to work anyway.
So, any thoughts on that IEditableObject functionality?
Regards, Stefan
Hi Stefan,
I tested the reported issue with my approach and when changing the cell and after that press ‘Esc’ button using the following event handler seems to roll back the prevois cell value:
private void XamDataGrid_PreviewKeyDown(object sender, KeyEventArgs e)
// Pressing ESCAPE rolls back the entire row.
if (e.Key == Key.Escape)
((XamDataGrid)sender).ExecuteCommand(DataPresenterCommands.DiscardChangesToActiveRecord);
((XamDataGrid)sender).ExecuteCommand(DataPresenterCommands.EndEditModeAndDiscardChanges);
e.Handled = true;
I believe that this is the best approach for achieving the desired functionality.
Actually the rollback does not always work. If you start the application, change the blue icon to red, and then click another cell with your mouse, then it is indeed correct like you said. An error is displayed and you can still press ESC to roll back.
But! If you restart the application, change the blue icon to red and press ENTER to commit the value, then the EndEdit is called even if the row is invalid. The validation error is still displayed however. So, the problem only seems to occur when using the ENTER key.
For a moment there, I thought I had solved the problem. When you add the following code to the PreviewKeyDown:
else if (e.Key == Key.Enter)
if (grid.ActiveCell.IsInEditMode)
((XamDataGrid)sender).ExecuteCommand(DataPresenterCommands.EndEditModeAndAcceptChanges);
e.Handled =true;
} }
It seems to solve the problem at first, but is also messes up the way the XamComboEditor works because it is no longer possible to change the XamComboEditor by means of keyboard. In other words, it works when changing the blue icon to red with the mouse and then press ENTER to end edit mode, but it breaks the combobox when changing the blue icon to red with the keyboard (F2 to enter edit mode, then ALT-Arrow down to open the combobox, then select red and press ENTER).
We're getting closer though! The only thing missing (I think) is some mechanism to detect whether the cell is about to be committed, or the cell's editor is about to change its current value. (And it's not just about combo boxes, the same could apply to other editor types as well.) We'd only need to override the logic for the ENTER key when committing the cell.
I am glad that you have managed to resolve your issue.
I found the solution! I can check the editor before executing the command like so:
if (grid.ActiveCell != null && grid.ActiveCell.IsInEditMode)
CellValuePresenter cvp = CellValuePresenter.FromCell(grid.ActiveCell);
bool ignore = false;
if (cvp.Editor is XamComboEditor && ((XamComboEditor)cvp.Editor).IsDropDownOpen)
ignore =true;
if (cvp.Editor is XamDateTimeEditor && ((XamDateTimeEditor)cvp.Editor).IsDropDownOpen)
if (!ignore)
} } }
And this way it works for both keyboard and mouse. The only question that remains is what happens when custom value editors are used because currently I explicitely check for XamComboEditor and XamDateTimeEditor, but I can worry about that when it's actually necessary.