WPF Tutorial – How to use IDataErrorInfo in WPF

In this post I shall explain how to use IDataErrorInfo in a WPF Application. IDataErrorInfo takes into consideration the powerful databinding that WPF has provided. If you are Binding your controls using the Binding techinque, then for validations, IDataErrorInfo is recommended as it is easier to implement.
Lets get started!
First we will create a User class :
























































































    class User:IDataErrorInfo,INotifyPropertyChanged
    {
 
        private String _firstName;
        public String FirstName
        {
            get { return _firstName; }
            set
            {
                _firstName = value;
                OnPropertyChanged("FirstName");
            }
        }
 
        private String _lastName;
        public String LastName
        {
            get { return _lastName; }
            set
            {
                _lastName = value;
                OnPropertyChanged("LastName");
            }
        }
 
        private int _age;
        public int Age
        {
            get { return _age; }
            set
            {
                _age = value;
                OnPropertyChanged("Age");
            }
        }
 
        #region IDataErrorInfo Members
 
        public string Error
        {
            get { return String.Empty; }
        }
 
        public string this[string columnName]
        {
            get
            {
                String errorMessage = String.Empty;
                switch (columnName)
                {
                    case "FirstName":
                        if (String.IsNullOrEmpty(FirstName))
                        {
                            errorMessage = "First Name is required";
                        }
                        break;
                    case "LastName":
                        if (String.IsNullOrEmpty(LastName))
                        {
                            errorMessage = "Last Name is required";
                        }
                        break;
                    case "Age":
                        if (Age < 1)
                        {
                            errorMessage = "Age cannot be less than one";
                        }
                        break;
                }
                return errorMessage;
            }
        }
 
        #endregion
     
        #region INotifyPropertyChanged Members
 
        public event PropertyChangedEventHandler  PropertyChanged;
        private void OnPropertyChanged(String propertyName)
        {
            if(PropertyChanged!=null)
            {
                PropertyChanged(this,new PropertyChangedEventArgs(propertyName));
            }
        }
 
        #endregion
}
In the above class, I implemented two Interfaces, IDataErrorInfo to provide validation and INotifyPropertChanged to notify that the Property has changed.
You can see the IDataErrorInfo readonly properties.
The second one is what we need. It has a column name parameter, which will be the Properties of the User class.
For each property, we are assigning specific rules such as, the FirstName and the LastName should not be empty. The age should not be less than one. The errorMessage field will be initialised with the Error Message that you want to show when these rules are not followed.
Then there is a Users class which will inherit the ObservableCollection(of User). It will hold the collection of User.












class Users:ObservableCollection
 {
     public Users()
     {
         Add(new User()
         {
             FirstName = "Tarun",
             LastName = "Singh",
             Age = 22
         });
     }
 }
So now we can create a window to display our data.
Window
Window
And here is the XAML :
I shall XAML parts by parts:
Here is the Resources used :
Resources - TextBox
Resources - TextBox
Here I have created a style for all the textboxes. Note the TargetType, I have written it as {x:Type TextBox}, thus this style will be applied to all the Style in the Grid. Firstly, I have added a Trigger to set the ToolTip whenever there is a Validation Error.
Next I have provided the ErrorTemplate for the textbox. Basically whenever there is a validation we can provide our own template for it using AdornedElementPlaceHolder(pretty long one!). This will place a layer above the element, as in this I placed a Border above the TextBox with a Red BorderBrush. And then I have provided a TextBlock to the Right of the TextBox which will give a Red star indicating an error together with the ToolTip.
Next step will be disabling the Button when Validation fails in any of the TextBoxes.
Resources - Button
So here in the XAML, you can see I have added DataTrigger(ya i should have used a MultiDataTrigger with Conditions, but all the Conditions will have to be true so i will be coming with a solution for this!). Each datatrigger is bound to textboxes to check for Validation Errors, if errors found then, the button will be disabled! Cool isn’t it!
Now lets turn our attention to the XAML of Controls that we have used as this part does the Binding.
SO here it is :
XAML - Controls
XAML - Controls
There are two important things to take care of.
First is the use of ValidatesOnErrors. This should be declared in Binding Expression and set to True if we are using IDataErrorInfo.
Second is the use of Binding.ValidationRule. There are two reasons why we are using this is. First is because if we leave Age empty, no validation will be evaluated. Second is if on adding characters to the age, still no validation will be fired. Try removing the Binding.ValidationRule and you can see the difference. So to handle this, we will create a class AgeValidation to solve this problem.
Here is the class:






















class AgeValidation:ValidationRule
{
    public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
    {
        int age;
        Boolean noIllegalChars;
        noIllegalChars = int.TryParse(value.ToString(), out age);
 
        if (value.ToString().Length < 1)
        {
            return new ValidationResult(false,"Age field cannot be empty");
        }
        else if(noIllegalChars==false)
        {
            return new ValidationResult(false, "Illegal Characters");
        }
        else
        {
            return new ValidationResult(true, null);
        }
    }
}
This class inherits the ValidationRule and overrides the ValidationRule function. Here we can check for illegal characters and also check for empty entry in the Textfield. This function will return the Error Message that you want to show. Awesome! :)
Do add the namespace to locate this class in the assembly.
xmlns:local=”clr-namespace:WpfApplication1″;
Finally in the code-behind of our window, in the class constructor, we can provide the DataContext like below:








public partial class Window2 : Window
{
    public Window2()
    {
        InitializeComponent();
        DataContext = new Users();
    }
}
Lets see its working now!
Running Example Cool!
That’s it!
So this is how Validation is handled in WPF.
Hope you enjoyed it! Do leave your comments, suggestions, feedbacks on how you liked this article. :)
Have a nice day!

Comments