Pages

Monday, June 21, 2010

Validate your application using IDataErrorInfo

As we move ahead  with WPF, we find lots of flexibilities that WPF provides for UI development. One of such is to define ValidationRule to work with controls bound with Data elements. In this article, I will discuss how easily you can impose custom validation to your DataElements by doing the entire thing from within the class itself.

First let us create the DataElement for which I need to use Data validation. As we know Binding needs few things like INotifyPropertyChanged event to handle binding, it needs IDataErrorInfo to handle ValidatesOnDataErrors calls. So the first thing that you need to do is to create a class from IDataErrorInfo interface.

Implementation

public class Contact : IDataErrorInfo
    {
        private string _Name;
        private string _desig;

        public string Name
        {
            get { return _Name; }
            set { _Name = value; }
        }

        public string Designation
        {
            get { return _desig; }
            set { _desig = value; }
        }

        #region IDataErrorInfo Members

        public string Error
        {
            get { return "Error occurred"; }
        }

        public string this[string columnName]
        {
            get 
            {
                return this.GetResult(columnName);
            }
        }

        private string GetResult(string columnName)
        {

            PropertyInfo info = this.GetType().GetProperty(columnName);
            if (info != null)
            {
                string value= info.GetValue(this, null) as string;
                if (string.IsNullOrEmpty(value))
                    return string.Format("{0} has to be set", info.Name);
                else if(value.Length < 5)
                    return string.Format("{0}'s length has to be at least 5 characters !", info.Name);
            }
            return null;
        }
        #endregion
    }

In this class you can see I have implemented it from IDataErrorInfo which lets me to impose Validation on Text that binds these properties. To induce this bindings, you need to use :

<Window.Resources>
        <AppCode:Contact x:Key="dsContact"/>  
</Window.Resources>

<TextBox BorderBrush="Black" Margin="80,54.04,19,74.96" Height="22" 
                 Name="txtLastName" Grid.Row="1" VerticalAlignment="Top" Text="{Binding Source={StaticResource dsContact}, UpdateSourceTrigger='LostFocus', Path=LastName, ValidatesOnDataErrors=True}">


Thus the data is bound with the Properties. The ValidatesOnDataErrors will automatically invoke indexer for Errors and gets the message based on when Data is modified inside the control.

To show the error message you can create a style which highlights the errorinfo over the control. I have used the general style to do so.

<Style TargetType="{x:Type TextBox}">
            <Style.Triggers>
                <Trigger Property="Validation.HasError" Value="true">
                    <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
                    <Setter Property="Control.Background" Value="Pink" />
                </Trigger>
            </Style.Triggers>
        </Style>
Thats it, you are done with it. I will discuss more about this later.
Thanks for reading.

5 comments:

  1. Good one. Looking for it.

    ReplyDelete
  2. Amazing work my friend. Looks cool.

    Thanks for you post.

    ReplyDelete
  3. Thank you guys..

    Give some more input guys ...not only specifying that you like it.

    ReplyDelete
  4. Very good article! Thanks!
    One question: How can I trigger all the validation rules at once? Need to implement a save button and would love all the validations to be called then... Any help is appreciated!

    Stefan

    ReplyDelete

Please make sure that the question you ask is somehow related to the post you choose. Otherwise you post your general question in Forum section.