Model-View-ViewModel (MVVM) – Part 4 – INotifyDataErrorInfo

In this next part, I’m going to discuss validation of your view models using the INotifyDataErrorInfo interface. Validation is an often ignored part of the Model-View-ViewModel (MVVM) story. If you need to create a form for your users to fill in (which is probably most applications, I would have thought), then you probably need to validate user input in some way and the INotifyDataErrorInfo interface can get you there.

INotifyDataErrorInfo Valid TextBox

INotifyDataErrorInfo Valid TextBox

INotifyDataErrorInfo Invalid TextBox

INotifyDataErrorInfo Invalid TextBox

In the example above you can see a name text box which requires text, to be in a valid state. In the valid state there is a big green tick next to the text box and conversely in an invalid state, there is a big yellow warning sign, the text box background becomes pink and you get a nice tool-tip telling you what the error is. By the way, this example is taken from my Elysium Extra WPF project which is freely available on CodePlex.

How Does It Work?

You can see the interface and its corresponding event arguments below. If the name property in our view model changes and is empty then the state of our view model is invalid, we can raise the ErrorsChanged event, set the HasErrors property to return true and make any calls to GetErrors return a list of the errors (In our case we only have one but there could be multiple errors).

That’s a fair amount of work and a base class to do all that makes life much easier. So what are the main aims of a base class implementing INotifyDataErrorInfo?

  • Integration – I usually want to raise an error in response to a property changing. So, we probably want to also implement INotifyPropertyChanged. Handily, I showed how best to create a base class for that in my last article in this series. So our new base class can inherit from the NotifyPropertyChanges base class.
  • Performance – Performance is king. It needs to be fast and I mean really fast. You can’t afford for your UI to freeze up while your view model works out if it has an error to raise or not. Some validation frameworks use an attribute based approach but this requires reflection so we will not be using that here.
  • Reactive Extensions (Rx) – Events are old school, I want an observable error changed event notification system instead of the ‘ErrorsChanged’ C# event.
  • Human Error – I don’t want to raise error change events for properties that don’t exist by accident.
  • Has it Really Error’ed – I don’t want to raise a error changed event twice by accident or if it has not really error’ed.

So, without further ado, here is my implementation. Note that there are three classes:

Simple Example

An example of how you can use this base class is as follows.

As you can see, our view model has two properties and as shown in the last post in the series we are using the SetProperty method to raise PropertyChanged events. The only bit I’ve added for validation is in the static constructor containing the three validation rules.

The Name property has a single rule applied to it. When the name is empty a validation error is raised. The LimbsRemaining property has two rules and when it is less than zero or more than four, validation errors are raised auto-magically.

Under the covers, each time the PropertyChanged event is raised, we apply the corresponding rule relating to the property and if the rule fails, we raise the ErrorsChanged event, raise a PropertyChanged event for the HasErrors property (Which is now true) and finally ensure that any calls to GetErrors now returns the error shown in the rule.

Extensibility

The DelegateRule<T> class shown above is a really easy way to provide nice, simple rules. If you need something more complex you can create your own rule by inheriting from the Rule<T> base class. An example of this could be a custom rule to validate an email address or telephone number.

Using Reactive Extensions (Rx) to Replace the ErrorsChanged Event

C# events are old school. Reactive Extensions (Rx) provides a cleaner and far more powerful drop-in replacement for C# events. I’m not going to go over the advantages of Reactive Extensions here but you can take a look at a series of blog posts I’ve done in the past.

We can hide the ErrorsChanged C# event by explicitly implementing the interface (Click here for details on implicit versus explicit implementations of interfaces).

The ErrorsChanged C# event can still be accessed by first casting the object to INotifyDataErrorInfo. Validation in XAML languages, which uses this interface continues to work. Our new Reactive Extensions (Rx) observable event called ‘WhenErrorsChanged’ of type? IObservable<string> (The string is the property name) is now the default method of subscribing for error changed events and we’ve hidden away the old C# event.

INotifyDataErrorInfo Support

The INotifyDataErrorInfo interface is supported by most XAML frameworks including WPF, Silverlight and Windows Phone. Currently WinRT does not support the interface at the time of writing but you can bet that they will in future and in the mean time you can use the WinRT XAML Validation library in conjunction with the code below to plug this gap.

Quick nod to IDataErrorInfo

This interface used to be used for validation but was replaced by INotifyDataErrorInfo. The new interface provides a much nicer API which is easier to code against and better performance. If you are still using the old interface, its time to make the change.

Conclusions

I’ve been tweaking this base class for the last few years and feel I’ve got a fairly good balance. I’ve not seen too many implementations of this interface, most blogs seem to cover INotifyPropertyChanged pretty well though. I’d be very interested if anyone has any comments or thoughts on improvements. Feel free to sound-off in the comments.