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 :
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.
So now we can create a window to display our data.
And here is the XAML :
I shall XAML parts by parts:
Here is the Resources used :
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.
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 :
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:
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:
Lets see its working now!
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!
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 } |
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 }); } } |
And here is the XAML :
I shall XAML parts by parts:
Here is the Resources used :
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.
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 :
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 ); } } } |
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(); } } |
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
Post a Comment