In my previous article I have discussed about the first two ways out of total four ways by which we can perform WPF validations. In this article I will discuss the validation using IDataErrorInfo.
Validation using IDataErrorInfo
- This is present since .NET 1.0
- It is supported in windows forms, WPF and carries forward to other XAML technologies also.
- IDataErrorInfo has two members which need to be implemented by the derived class.
- The members are ErrorProperty and Indexer.
- The interface is implemented on the Object which we bind to the WPF control.
- Here the property is first set to the value and then it comes at the Indexer property checking if the set value is perfect.Once we implement the IDataErrorInfo for the data object which we have to bind to, we need to set the ValidatesOnDataError = true in the XAML. I will use the same View model class which I have used in previous demos. The difference here is that I have to implement the IDataError info to the View Model class.
public class PersonVM: INotifyPropertyChanged, IDataErrorInfo { private string mobileNumber; public string MobileNumber { get { return mobileNumber; } set { mobileNumber = value; PropertyChanged(this, new PropertyChangedEventArgs("MobileNumber")); } } private string name; public string Name { get { return name; } set { name = value; PropertyChanged(this, new PropertyChangedEventArgs("Name")); } } public string Error { get { return string.Empty; } } public string this[string propertyName] { get { return GetErrorForProperty(propertyName); } } private string GetErrorForProperty(string propertyName) { switch (propertyName) { case "MobileNumber": Regex regex = new Regex(@"^\D?(\d{3})\D?\D?(\d{3})\D?(\d{4})$"); if (regex.Match(MobileNumber) == Match.Empty) return "Invalid Phone Format"; else return string.Empty; default: return string.Empty; } } public event PropertyChangedEventHandler PropertyChanged = delegate { }; }
and the XAML code for the text box is as shown below.
<Window x:Class="Validation.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:Validation" xmlns:string="clr-namespace:System;assembly=mscorlib" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"></ColumnDefinition> <ColumnDefinition Width="Auto"></ColumnDefinition> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition Height="Auto"></RowDefinition> </Grid.RowDefinitions> <TextBlock Text="Name " Height="30" Grid.Column="0" Grid.Row="0"></TextBlock> <TextBox Text="{Binding Name}" Grid.Column="1" Grid.Row="0" Height="30" Width="100"></TextBox> <TextBlock Text="Mobile Number " Height="30" Grid.Column="0" Grid.Row="1"></TextBlock> <TextBox Grid.Column="1" Grid.Row="1" Height="30" Width="100" Text="{Binding MobileNumber, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}"> </TextBox> </Grid> </Window>
In the above xaml I have provided the validation only for the MobileNumber field. The field will be validated whenever the property value is changed in the textbox. This is done using UpdateSourceTrigger=PropertyChanged in the binding. If we remove this property, the MobileNumber value will be validated only on lost focus from the textbox control.
In my next article I will discuss how to handle the validation asynchronously using INotifyDataErrorInfo.