Where to validate business rules in a view model only on save?

Topics: Feature requests
Jul 16, 2012 at 7:59 PM
Edited Jul 16, 2012 at 7:59 PM

I have a Customer ViewModel in which I would like to validate the uniqueness of the Code property when saving the view model.

I want to show the error in the InfoBarMessageControl just like the field validations already are (which are attribute based and present in the model class).

In my view I have bound the properties to the viewmodel using UpdateSourceTrigger=PropertyChanged.

When I show my view(model) the fields are nicely shown in the InfoBarMessageControl as required. So far so good.

Now I thought I had to add the business rule validation 'check for unique code' in the overriden method ValidateBusinessRules of the viewmodel.

However, when I set a breakpoint in ValidateBusinessRules I see it gets called every time a property in the view changes. I don not want that behaviour because the database call is relative expensive.

How can I delay the call to ValidateBusinessRules so that it occurs only when the OK button of the datawindow is pressed e.g. the viewmode is saved?

And if this is not possible how can I make sure that if I put the validation in the overridden Save method, the error message is stil displayed in InfoBarMessageControl? Is there a possibility to manually add an error to the ValidationResults so it will be displayed in the InforBarMessageControl?



Jul 18, 2012 at 6:44 AM
Edited Jul 18, 2012 at 6:46 AM

Did you try to use the DeferValidationUntilFirstSaveCall property on the viewmodel?

Jul 18, 2012 at 8:28 AM

Yes I have. This doesn't work, perhaps because I use UpdateSourceTrigger=PropertyChanged which fires validations after each key stroke. This is fine for simple fast validations. But now ValidateBusinessRules is called 3 times for each key stroke which is a real performance issue.

After removing UpdateSourceTrigger=PropertyChanged and using the defer property, the validation is deferred but now all validations are deferred. It would be nice to have the simple field validations all the time and the business rules validations only when saving the view model.

I see no other option than to check the unique business rule in de Save method and then communicate this to the user using the IMessageService. But I don't think this is a very nice solution. You now get two different ways of validation communication to the user.

Is there a way of knowing in ValidateBusinessRules that the Save has been called? That way I could only perform the check in ValidateBusinessRules when the view model is being saved.

Jul 19, 2012 at 5:32 AM

Why not use a simple boolean in the validation methods to allow business validation when ever you want?

Jul 19, 2012 at 7:47 AM
Edited Jul 19, 2012 at 7:48 AM

That is the direction in which I'm thinking too. But I don't (yet) know at what moment in the view model I should (or can) set this flag to be able to do this.

I can override the Save method, but this method seems to be called after validation is finished. So.... where do I set the boolean to true??

Jul 19, 2012 at 8:10 AM

Indeed, a bool would work. We can add a property IsSaving which you can check in your ValidateBusinessRules method.

Jul 19, 2012 at 8:14 AM

Since I don't know where to put the boolean myself, it would be great if Catel can provide it for me :)

Jul 19, 2012 at 8:15 AM

Will do.

Jul 19, 2012 at 8:55 AM

Any chance of an ETA?

Jul 19, 2012 at 9:04 AM

If you are lucky, this weekend. Have to merge lots of changes, and want to have some free time as well.

Jul 19, 2012 at 9:34 AM

I can perfectly understand the wish, and need, for some free time :)

Perhaps I could use a custom OK button on the DataWindow. Then I can hack (write my own) OnOkExecute as to introduce a boolean flag myself for the moment.

I do wonder how other people using Catel do Business rule validation and not having the problems I come across :)

Jul 19, 2012 at 7:35 PM

Released new nightly build via nuget

Jul 20, 2012 at 8:56 AM

Thanks. The new property seems to work great. Now hoping that the beta release doesn't break anything else :)