Tuesday, August 9, 2011

Validate Data using IDataErrorInfo in WPF


WPF Data binding supports for business layer data validation using IDataErrorInfo interface. IDataErrorInfo interface was exists earlier in Windows forms application. Microsoft added support for binding to report error using IDataErrorInfo interface in WPF 3.5 version. IDataErrorInfo interface has two properties one is string Error and another is string indexer. String indexer accepts property name and returns corresponding error.  To enable data validation using IDataErroInfo interface you must set ValidatesOnDataError property to True of binding object.

I have reused and modified example I demonstrated in my previous post Validation Rules in WPF. In that example I have added IDataErrorInfo interface and removed validation rules from XAML code. Let’s have a look on below modified example.

<Window.Resources>
    <local:Employee x:Key="EmployeeInformation" />
    <Style TargetType="{x:Type TextBox}">
        <Style.Triggers>
            <Trigger Property="Validation.HasError" Value="True">
                <Setter Property="ToolTip"
                    Value="{Binding RelativeSource=
                           {x:Static RelativeSource.Self},
                    Path=(Validation.Errors)[0].ErrorContent}" />
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Resources>
<Grid Margin="5">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="0.5*" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition  Height="0.20*"/>
        <RowDefinition Height="0.20*" />
        <RowDefinition Height="0" />
    </Grid.RowDefinitions>

    <TextBlock Text="Enter Name: " Grid.Column="0"
                Grid.Row="0" Margin="3"/>
    <TextBox Name="Name" Grid.Column="1"
                Grid.Row="0" Height="30" Margin="3">
        <TextBox.Text>
            <Binding Source="{StaticResource EmployeeInformation}"
                        Path="Name" ValidatesOnDataErrors="True" />
        </TextBox.Text>
    </TextBox>
    <TextBlock Text="Enter Age: " Grid.Column="0"
                Grid.Row="1" Margin="3"/>
    <TextBox Name="Age" Grid.Column="1"
                Grid.Row="1" Height="30" Margin="3">
        <TextBox.Text>
            <Binding Source="{StaticResource EmployeeInformation}"
                        Path="Age" ValidatesOnDataErrors="True" />
        </TextBox.Text>
    </TextBox>
</Grid>

public class Employee : INotifyPropertyChanged, IDataErrorInfo
{
    private string name;
    public string Name
    {
        get { return name; }
        set { name = value; OnPropertyChanged("Name"); }
    }
    private int age;
    public int Age
    {
        get { return age; }
        set { age = value; OnPropertyChanged("Age"); }
    }
    //Implements INotifyPropertyChanged
    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(string name)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(name));
    }
    //Implements IDataErrorInfo
    public string Error //WPF doesn't use this property
    {
        get { return null; }
    }
       
    //Data Validation here.
    public string this[string columnName]
    {
        get
        {
            switch (columnName)
            {
                case "Name":
                    {
                        return ValidateName(columnName);
                    }
                case "Age":
                    {
                        return ValidateAge(columnName);
                    }
            }
            return null;
        }
    }
    private string ValidateName(string columnName)
    {
        if (Name == null) return null;
        if (Name.All(c => char.IsLetter(c) || c == ' '))
            return null;
        return "Please enter only alphabets";
    }
    private string ValidateAge(string columnName)
    {
        if (age == 0) return null;
        if (age >= 18 && age <= 35)
        {
            return null;
        }
        return "Please enter Age between 18 to 35";
    }
}












See also –


No comments:

Post a Comment