Wish ValidationRules would easily integrate with IDataErrorInfo and ViewModel in MVVM

Topics: Prism v4 - WPF 4
Jul 16, 2012 at 3:55 PM
Edited Jul 16, 2012 at 4:13 PM

I've been looking at validation with Prism for WPF applications. I'm new to validation in WPF in general, but have been looking through various examples and my books. Here's my thoughts.

My WPF book shows data binding validation by implementing your own ValidationRules. I really like this approach because it would allow me to simply implement reusable validation logic rules (e.g. StringIsNotEmpty, IsDirectoryPath) and specify them at the time of binding in the XAML code. Once I wrote my ValidationRules, I would not need any C# code to implement most validation logic. Awesome.

However, if you think of this in context of MVVM with Prism, this solution is not really acceptable. It relies on the view (UI) to implement the validation logic. Even if you implemented validation logic in the accept command for a form in your ViewModel, there doesn't seem to be a good way to connect the two together, and you would be doing the work for validation twice for no reason.

Of course, the Prism book says that you should be using IDataErrorInfo and there is example of it in the Commanding Quickstart. That example is nicely done. However, the validation logic is hard coded in the ViewModel. This requires me to write code and perhaps leaves me more prone to errors. Sure, I could implement my own static validation functions that are reusable, but it still doesn't seem as eloquent as adding ValidationRules in XAML. Also, similar to the difference between INotifyPropertyChanged and NotifcationObject, hard coded validation on properties breaks after refactoring code changes.

I guess I'm wondering what the best approach is with validating using IDataErrorInfo that I can reuse validation logic code. Create my own static validation utility class? I just don't want to reinvent the wheel every time I need a certain validation logic. I want to create the rules once in a common project and re-use it everywhere. I'm sure I can do the static classes, or similar. But, is there a better solution?


Developer
Jul 16, 2012 at 7:45 PM

Hi Alan,

Based on my understanding, there is not a "better" approach, in my opinion which approach you should use would depend mostly on your personal preferences and the requirements of your scenario.

What is more, you could have both ValidationRules to validate things like formatting, empty fields, etc, and validation in the view model / model through the  IDataErrorInfo interface to validate business related information. For example, in a TextBox that binds to a numeric type property, you could validate the text to check if it's a number though a ValidationRule and then validate if the value is in the correct range in the view model.

Regarding this, I believe you could find the following articles useful:

I hope you find this useful,

Damian Cherubini
http://blogs.southworks.net/dcherubini

Jul 17, 2012 at 4:41 PM
Edited Jul 17, 2012 at 4:42 PM

Thanks for the response. What you said about the ability to split validation between the view and view model makes sense. If the View is bound to an integer, then there is no way that it will accidentally get a string value assigned. I assume the default behavior is the ExceptionValidationRule with an integer parse exception string. If I desired to provide a better message, I could add custom ValidationRules to the binding.

The Attributes are a nice example of another way in which validation can be done declaratively. But, I think for my preferences, I will stick to implementing my own ValidatingViewModel base class which implements IDataErrorInfo. I have added a GetPropertyName(Expression<Func<T>> property) method to it as a helper method to avoid magic strings using lambda expressions similar to NotificationObject versus INotifyPropertyChanged. I have also added some basic logic to it similar to the Commanding Quickstart's implementation of the OrderPresentationModel.