Share via


Data Validation in 3.5

A cool new feature in the Data area in 3.5 is the support for IDataErrorInfo. Let's take a look at the data validation model in 3.5 by starting with a memory refresher of that in 3.0. We end with a section that discusses how to choose between the different approaches.

3.0 Validation Model

In 3.0, you would create a custom ValidationRule or use the built-in ExceptionValidationRule this way:

                <Binding Source="{StaticResource data}" Path="Age"

                         UpdateSourceTrigger="PropertyChanged">

                    <Binding.ValidationRules>

                        <ExceptionValidationRule/>

                    </Binding.ValidationRules>

                </Binding>

If the ExceptionValidationRule has been associated with the binding and there’s an exception when the binding engine attempts to set the property on the source, then the binding engine creates a ValidationError with the exception and adds it to the Validation.Errors collection of the bound element. You can use the errors in the collection to provide additional visual feedback (in addition to the default red border for the TextBox in error). You can read more about that in the last section of the Data Binding Overview.

3.5 IDataErrorInfo Support

In 3.5, the data binding engine adds the support for business-layer validation by supporting IDataErrorInfo. For example, the following Person class implements IDataErrorInfo to specify that the Age of a Person is not valid if it’s less than 0 or greater than 150.

 

    public class Person : IDataErrorInfo

    {

        private int age;

        public int Age

        {

            get { return age; }

            set { age = value; }

        }

        public string Error

        {

            get

            {

                return null;

            }

        }

        public string this[string name]

        {

            get

            {

                string result = null;

                if (name == "Age")

                {

                    if (this.age < 0 || this.age > 150)

                    {

                        result = "Age must not be less than 0 or greater than 150.";

                    }

                }

                return result;

            }

        }

    }

To use the IDataErrorInfo implementation logic you add the DataErrorValidationRule to the ValidationRules collection, like so:

                <Binding Source="{StaticResource data}" Path="Age"

                         UpdateSourceTrigger="PropertyChanged">

                    <Binding.ValidationRules>

                        <DataErrorValidationRule/>

                    </Binding.ValidationRules>

                </Binding>

If an error is raised, the binding engine creates a ValidationError with the error and adds it to the Validation.Errors collection of the bound element. The lack of an error clears this validation feedback, unless another rule raises a validation issue.

 

Alternative Syntax

In 3.5, we also provide a “short-hand” for using the DataErrorValidationRule and the ExceptionValidationRule. Instead of adding the DataErrorValidationRule explicitly like in the above snippet, you can set the ValidatesOnDataErrors attribute, like so:

                <Binding Source="{StaticResource data}" Path="Age"

                         UpdateSourceTrigger="PropertyChanged"

                         ValidatesOnDataErrors="True" />

The “short-hand” for the ExceptionValidationRule is the ValidatesOnExceptions attribute.

When to use Validation Rules vs. IDataErrorInfo

Whether you should use a rule that derives from ValidationRule (a custom rule or ExceptionValidationRule) or implement IDataErrorInfo depends on your scenario.

The following table and the validation procedure in the next sub-section describe the things you should take into consideration:

ValidationRules (custom ValidationRule or ExceptionValidationRule)

IDataErrorInfo

UI or business-layer validation logic

The validation logic is detached from the data source, and can be reused between controls.

The validation logic is closer to the source.

One data source, multiple apps

This is the logical choice if you have one data source that is used by two different apps and you want to validate it differently in each app.

 

WinForms to WPF

 

This is the logical choice if you are porting your app from WinForms to WPF.

Validation Procedure

The binding engine follows the following logic during the validation process:

1. Evaluate all the custom validation rules (but not the ExceptionValidationRule or the DataErrorValidationRule). If one or more of the custom rules fails, then stop and mark the value as invalid.

2. Call the setter. If this throws an exception, and if the ExceptionValidationRule was enabled, then stop and mark the value as invalid.

3. If the DataErrorValidationRule was enabled, check the IDataErrorInfo for the property. If this indicates an error, then stop and mark the value as invalid.

4. Mark the value as valid.

The attached sample has a TextBox that binds to the Age property of a Person object. The Person class implements IDataErrorInfo, as shown in the earlier snippet.

 

The TextBox binding uses the ExceptionValidationRule to catch exceptions raised during the setter call of the source property, as shown in the following screenshot:

The business object layer provides the logic for out-of-range errors (as defined by the IDataErrorInfo implementation):

WPF Data Validation.zip

Comments

  • Anonymous
    October 02, 2007
    PingBack from http://www.artofbam.com/wordpress/?p=4712

  • Anonymous
    October 03, 2007
    Are there any plans to add built-in support for Enterprise Library's Validation Application Block in 3.5?

  • Anonymous
    October 03, 2007
    Hi Alex, No, there won't be built-in support for that in 3.5. Thanks, Tina

  • Anonymous
    October 05, 2007
    A cool new feature in the Data area in 3.5 is the support for IDataErrorInfo. Let&#39;s take a look at

  • Anonymous
    January 27, 2008
    How to do user input validation in WPF without doing DataBinding

  • Anonymous
    February 12, 2008
    SDK Team, You can also include the Binding statement withint the TextBox XAML, which shortens the code up a bit. <TextBox x:Name=”txtFirstName” Text=”{Binding Path=FirstName, UpdateSourceTrigger=LostFocus,         Mode=TwoWay, ValidatesOnDataErrors=True}” /> Cheers, Karl

  • Anonymous
    April 12, 2008
    Introduction WPF offers some rather good stuff when it comes to applying validation to binding expressions.

  • Anonymous
    July 24, 2008
    The comment has been removed

  • Anonymous
    July 25, 2008
    The comment has been removed

  • Anonymous
    August 28, 2008
    Problem: I am using .NET 3.5 SP1. WPF seems to have a bug with validation. Whenever there is a validation

  • Anonymous
    November 25, 2008
    原文地址:http://blogs.msdn.com/wpfsdk/archive/2007/10/02/data-validation-in-3-5.aspx 本文讲述了3.5中新增的用Idata...

  • Anonymous
    November 25, 2008
    原文地址:http://blogs.msdn.com/wpfsdk/archive/2007/10/02/data-validation-in-3-5.aspx 本文讲述了3.5中新增的用Idat...

  • Anonymous
    November 25, 2008
    原文地址:http://blogs.msdn.com/wpfsdk/archive/2007/10/02/data-validation-in-3-5.aspx 本文讲述了3.5中新增的用...

  • Anonymous
    February 10, 2009
    关于WPF数据绑定是什么,请参考DataBindingOverview。 关于WPF数据绑定的Validation更多细节,请参考DataValidationin3.5。 关于WPF数据...

  • Anonymous
    February 25, 2009
    さて、前回のエントリでは Windows フォームにおける双方向データバインドの基本的な使い方を解説しました。要点をまとめると、以下の通りとなります。 双方向データバインドを用いると、データソースから

  • Anonymous
    November 10, 2010
    Thanks a million! Great post!