WPF and Silverlight Validation with IDataErrorInfo and INotifyDataErrorInfo

In this post I’ll describe how to use the IDataErrorInfo and INotifyDataErrorInfo interfaces to perform validation in WPF and Silverlight.
There are several kinds of validations and the preferrable approach in the MVVM pattern is using the IDataErrorInfo or INotifyDataErrorInfo interface.
But this approach doesn’t behave as expected: it performs validation immediately after the launch of the view, whereas it would be better if the validation started only after a user has changed values. Also I would like to reuse some commonly used rules.

So I’ve created the helper class which performs all the necessary work. This class is similar to the class from the FluentValidation library, but it has less code and more flexible to me.
Here is the example of such validation:

    public class PersonViewModel : IDataErrorInfo, INotifyPropertyChanged
    {
        private ModelValidator _validator = new ModelValidator();

        public PersonViewModel()
        {
            //Six validation rules
            this._validator.AddValidationFor(() => this.FirstName).NotEmpty()
				.Show("Enter a First Name");
            this._validator.AddValidationFor(() => this.LastName).NotEmpty()
				.Show("Enter a Last Name");

            this._validator.AddValidationFor(() => this.Age).NotEmpty()
				.Show("Enter an age");
            this._validator.AddValidationFor(() => this.Age).Between(0,99)
				.Show("The age must be between 0 and 99");

            this._validator.AddValidationFor(() => this.Email)
				.When(() => this.IsSubscribe).NotEmpty()
				.Show("Enter an email address");
            this._validator.AddValidationFor(() => this.Email)
				.When(() => this.IsSubscribe).EmailAddress()
				.Show("Enter a valid email address");
            //Validates on changes of properties
            this.PropertyChanged += (s, e) => this._validator.ValidateProperty(e.PropertyName);
        }

        public string Error
        {
            get { throw new NotImplementedException(); }
        }

        public string this[string columnName]
        {
            get { return this._validator.GetErrors(columnName).FirstOrDefault(); }
        }

There is only 4 steps:
1. Create a variable of the ModelValidator type
2. Add necessary validation rules
3. Update validation every time when a property has been changed
4. Return cached errors inside the indexer property.

Actually it is not so obligatory to implement the 3rd step and update validation inside the PropertyChanged event handler. You can remove that line and call the ValidateAll method after a user clicks the Save button. But validation on changes is more preferrable solution.

I’ve added some predefined validation rules, if they aren’t enough, you can use the Must method with your own functions.
1. NotNull – the property value shouldn’t be null.
2. NotEmpty – if the property is of the string type, checks whether the string is null or consists of whitespaces. If of any other type – this rule is the same as NotNull.
3. Between – checks whether the property value is within a specific range. Works with strings as well as with numbers, so it’s not necessary to parse strings in view models.
4. EmailAddress – if the string value isn’t null, it should be a valid e-mail address.
5. Must – any user-defined validation function. For example: this._validator.AddValidationFor(() => this.LastName).Must(() => this.LastName.Length < 10).Show("Last name should not exceed 10 characters");

To implement this validation, you should copy 3 files with 2 classes to your project.
Here is the completed project where you can take all the necessary classes: WpfValidation.zip

Update
I’ve also added the validation for Silverlight both with IDataErrorInfo and INotifyDataErrorInfo:
The image illustrating validation errors in Silverlight
The source code you can download here: SilverlightValidation.zip

Advertisements

6 Responses to WPF and Silverlight Validation with IDataErrorInfo and INotifyDataErrorInfo

  1. Pingback: Windows Phone 7 Validation « Silverlight, WPF and Windows 8 Development

  2. Pingback: INotifyDataErrorInfo not raising error changed in code behind | PHP Developer Resource

  3. Anonymous says:

    Very nice implementation 🙂
    Thank you for sharing

  4. Alyce says:

    Thank you ever so much, a real lifesaver after days of searching!

  5. Anonymous says:

    Where is save button in WpfValidation ???

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: