-2

I have a C1DataGrid with one column and I want to be able to validate the data when I commit a new row in the grid.

So far I tried to throw an exception in the setter of this property. This validates the data while I am typing it in the text box correctly (throws an exception), but I am still able to commit the new row.

Furthermore I would like to only do the validation when I commit my new row and not after every new character I write.

Could someone show me how to do it? Many thanks!

MuriTuri
  • 7
  • 4

1 Answers1

0

You should implement inotifydataerrorinfo

https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.inotifydataerrorinfo?view=net-7.0

The easy way to do that is use the community mvvm toolkit

Inherit the viewmodel you're using for each item from Observablevalidator Add your validation attribute(s), or custom validation

https://learn.microsoft.com/en-us/windows/communitytoolkit/mvvm/observablevalidator

You could then check IsValid or HasErrors in the CommittingEdit event and stop it committing

https://www.grapecity.com/componentone/docs/wpf/online-datagrid/C1.WPF.DataGrid.4.5.2~C1.WPF.DataGrid.C1DataGrid~CommittingEdit_EV.html

The datagrid itself might automatically check HasErrors, I'm not familiar with C1Datagrid

Bear in mind that what inotifydataerrorinfo is doing is telling you your viewmodel has bad data in it. You then have to do something about it. Revert the change from a cached version or something.

It is because of this that I would usually keep any "original" OK data. Have the user edit a copy of any item separately from that and then only replace that original item ( or add a new one to a collection ) if it is definitely valid.

With a datagrids where the user can just edit like it's excel, you're better stopping them actually entering any bad data.

I only use this for quite simplistic scenarios like only entering integers or some such. The way I handle that is with an attached behavior which will essentially just not let the user type or paste invalid data in. There are obvious inherent limitations to this approach.

Another thing to consider is a binding ValidationRule. https://learn.microsoft.com/en-us/dotnet/desktop/wpf/data/how-to-implement-binding-validation?view=netframeworkdesktop-4.8

These work as the user enters and will stop invalid data transferring to the viewmodel property. You still have bad data in the datagrid though. So the user types bad stuff, the cell should respond and turn red or whatever. But you still have your bad stuff there in your view.

Andy
  • 11,864
  • 2
  • 17
  • 20
  • Thank you very much for your help! I implemented the "INotifyDataErrorInfo" interface and also added the validation. The validation works fine while I am typing a new row (it shows the error) but I can still hit "Enter" and the new row will be added without any problems. In the CommittingEdit event I check if the row is valid and it returns true... The row has no errors for some reason. – MuriTuri Jan 24 '23 at 15:10
  • The viewmodel instance should HasErrors = true if the value has transferred to the viewmodel and it shows you an error. – Andy Jan 24 '23 at 15:15
  • Yes, but how do I access it in the CommittingEdit event? The CommittingEdit event is in the Model.xaml.cs and not in the ViewModel itself. Thanks a lot again for your help! – MuriTuri Jan 24 '23 at 16:03
  • The event gets DataGridEndingEditEventArgs which has a row property. I should think that'll either be a UI row in which case it's datacontext would be the viewmodel. Or it might be the viewmodel. – Andy Jan 24 '23 at 16:10
  • Yes, you are right! Thank you! But how do I stop the commit now? The DataGridEndingEditEventArgs has a property called "Cancel". When I set this to true, nothing really happens. – MuriTuri Jan 25 '23 at 10:47
  • I don't use this datagrid control but the documentation says. This event typically occurs when the user press enter or tab in an editing cell. You can cancel the event setting DataGridEndingEditEventArgs.Cancel to true. – Andy Jan 25 '23 at 11:13
  • I noticed this: https://www.grapecity.com/blogs/validation-using-idataerroinfo-in-wpf-c1datagrid But really, you should edit a copy of your data. Then commit only valid changes to your "real" data. Once you have invalid data in a viewmodel, you don't want to use it. This is why I would usually have any datagrid read only. Edit in a separate panel with a copy of the selected item. I can then fine tune validation and commiting any edits because I control what's in that panel. – Andy Jan 25 '23 at 11:19
  • Kind of by definition, if inotifypropertyerrorinfo returns HasErrors, that means you have bad data in your viewmodel. – Andy Jan 25 '23 at 11:30