I've got a DataGrid that I'm binding to an ObservableCollection of "Customer" classes, implementing IDataErrorInfo. One of the properties on the Customer class is an int, and in my IDataErrorInfo implementation I check that it's within a valid range, e.g.:-
public class Customer : IDataErrorInfo
{
public int PercentDiscount { get; set; }
... other properties & methods removed for clarity
public string this[columnName]
{
get
{
if (PercentDiscount < 0 || PercentDiscount > 10)
return "Percent Discount is invalid";
}
}
}
In my XAML code-behind I handle a couple of events. In the PreparingCellForEdit event I store a reference to the row being edited:-
private void DataGrid_PreparingCellForEdit(object sender, DataGridPreparingCellForEditEventArgs e)
{
_rowBeingEdited = e.Row;
}
Then in the RowEditEnding event, I take some action if the row is in an invalid state (in my case I revert the Customer properties back to their previous "good" values):-
private void DataGrid_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e)
{
if (_rowBeingEdited != null)
{
var errors = Validation.GetErrors(_rowBeingEdited);
if (errors.Count > 0)
{
.. do something
}
}
}
This works fine if the user enters a numeric value that fails my validation rule, but if the user enters a non-numeric value then the RowEditEnding event never fires and the cell remains in an edit state. I assume it's because WPF fails to bind the non-numeric value to the int property. Is there any way I can detect/handle when this happens?
Last resort is to change the PercentDiscount property to a string, but I'm trying to avoid going down this route.
Edit - I've just found that I can successfully handle both types of error using the CellEditEnding event instead of RowEditEnding. A new problem has appeared though - if I enter an invalid value into the cell then press Enter, the underlying property doesn't get updated, so when CellEditEnding fires Validation.GetErrors is empty. The end result is that the row leaves edit mode but still shows the invalid value in the cell with red border. Any idea what's going on now?
This may not be much of an answer especially since you already mentioned it, but I've fought with DataGrid validation for a while and ended up resorting to making my backing values be strings. You'll notice in the output window of the debugger that a binding or conversion exception happens when you type an alpha character into a DataGridColumn bound to an int.
You can get different behavior by changing the UpdateSourceTrigger, or by putting a converter in between the binding and the property, but I never got exactly what I needed until I backed the values with strings.
I suppose you could also try creating your own DataGridNumericColumn derived from DataGridTextColumn and maybe you'd have more control over the binding/validation behavior.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With