IDataErrorInfo Interface
Defines members that data entity classes can implement to provide custom validation support.
Namespace: System.ComponentModel
Assembly: System (in System.dll)
The IDataErrorInfo type exposes the following members.
This interface enables data entity classes to implement custom validation rules and expose validation results to the user interface. You typically implement this interface to provide relatively simple, client-side validation logic.
To provide asynchronous or server-side validation logic, implement the INotifyDataErrorInfo interface instead.
In general, new entity classes for Silverlight should implement INotifyDataErrorInfo for the added flexibility instead of implementing IDataErrorInfo. The IDataErrorInfo support enables you to use many existing entity classes that are written for the full .NET Framework. Other validation options are also available, such as the use of data attributes. For more information, see Data Binding.
IDataErrorInfo Members
The IDataErrorInfo.Item property returns a single validation error message. The Error property returns a single error message for the entire object. Each of these single messages can represent multiple errors. If you want to represent multiple errors by using multiple custom error objects, implement the INotifyDataErrorInfo interface instead. This enables more detailed error reporting in the user interface (UI).
Data Binding Support
The Silverlight binding engine provides built-in support for IDataErrorInfo. To enable this support, bind a control to a property of an entity that implements IDataErrorInfo, and set the Binding.ValidatesOnDataErrors property to true. Then, whenever a bound entity property changes value, the binding engine validates the new value by passing the property name to IDataErrorInfo.Item. Note that the binding engine never uses the Error property, although you can use it in custom error reporting to display object-level errors.
The binding engine uses the validation results to update the Validation.Errors collection for that binding. First, the binding engine removes any existing errors for the bound property that originate from exceptions or from IDataErrorInfo validation. Then, if the new value is not valid, the binding engine adds a new error for the property.
You can use ValidatesOnExceptions and ValidatesOnDataErrors at the same time; however, any exceptions that occur will prevent IDataErrorInfo validation.
Error Reporting
The Validation.Errors collection provides a binding source for error reporting in the user interface. Several controls bind to this collection from their default control templates.
To provide custom error reporting, you can replace the default templates with customized versions. For more information, see Control Customization. You can also set the Binding.NotifyOnValidationError property to true and handle the FrameworkElement.BindingValidationError event. This event occurs each time an error is added or removed for a particular binding. Some controls, such as ValidationSummary, require this mechanism instead of using the Validation.Errors collection.
The following example code demonstrates how to implement IDataErrorInfo. This example uses the same error reporting structure as the example for the INotifyDataErrorInfo interface. However, in the IDataErrorInfo implementation, multiple errors for a single property are combined into a single error message. This limits the options for custom error reporting. Additionally, the IDataErrorInfo interface does not support the future addition of asynchronous validation rules.
Imports System.ComponentModel Public Class Product Implements IDataErrorInfo Private idValue As Integer Public Property Id As Integer Get Return idValue End Get Set(ByVal value As Integer) If IsIdValid(value) AndAlso idValue <> value Then idValue = value End Set End Property Private nameValue As String Public Property Name As String Get Return nameValue End Get Set(ByVal value As String) If IsNameValid(value) AndAlso nameValue <> value Then nameValue = value End Set End Property ' Validates the Id property, updating the errors collection as needed. Public Function IsIdValid(ByVal value As Integer) As Boolean Dim isValid = True If value < 5 Then AddError("Id", ID_ERROR, False) isValid = False Else RemoveError("Id", ID_ERROR) End If If value < 10 Then AddError("Id", ID_WARNING, True) Else RemoveError("Id", ID_WARNING) End If Return isValid End Function ' Validates the Name property, updating the errors collection as needed. Public Function IsNameValid(ByVal value As String) As Boolean Dim isValid = True If value.Contains(" ") Then AddError("Name", NAME_ERROR, False) isValid = False Else RemoveError("Name", NAME_ERROR) End If If (value.Length > 5) Then AddError("Name", NAME_WARNING, True) Else RemoveError("Name", NAME_WARNING) End If Return isValid End Function Private errors As New Dictionary(Of String, List(Of String)) Private ReadOnly ID_ERROR = "Value cannot be less than 5." Private ReadOnly ID_WARNING = "Value should not be less than 10." Private ReadOnly NAME_ERROR = "Value must not contain any spaces." Private ReadOnly NAME_WARNING = "Value should be 5 characters or less." ' Adds the specified error to the errors collection if it is not already ' present, inserting it in the first position if isWarning is false. Public Sub AddError(ByVal propertyName As String, ByVal [error] As String, ByVal isWarning As Boolean) If Not errors.ContainsKey(propertyName) Then _ errors(propertyName) = New List(Of String)() If Not errors(propertyName).Contains([error]) Then If isWarning Then errors(propertyName).Add([error]) Else errors(propertyName).Insert(0, [error]) End If End If End Sub ' Removes the specified error from the errors collection if it is present. Public Sub RemoveError(ByVal propertyName As String, ByVal [error] As String) If errors.ContainsKey(propertyName) AndAlso errors(propertyName).Contains([error]) Then errors(propertyName).Remove([error]) If errors(propertyName).Count = 0 Then errors.Remove(propertyName) End If End Sub Public ReadOnly Property [Error] As String Implements IDataErrorInfo.Error Get Throw New NotImplementedException() End Get End Property ReadOnly Property Item(ByVal propertyName As String) As String _ Implements IDataErrorInfo.Item Get Return If(Not errors.ContainsKey(propertyName), Nothing, String.Join(Environment.NewLine, errors(propertyName))) End Get End Property End Class
<UserControl x:Class="IDataErrorInfoExample.MainPage" 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:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400"> <Grid x:Name="LayoutRoot" Background="White" Margin="10"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="200"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <TextBlock Grid.Column="1" Margin="3" Text="Product" FontWeight="Bold"/> <sdk:Label Grid.Row="1" Target="{Binding ElementName=IdTextBox}" Margin="3" HorizontalAlignment="Right"/> <TextBox x:Name="IdTextBox" KeyDown="TextBox_KeyDown" Grid.Column="1" Grid.Row="1" Margin="3" MaxLength="5" Text="{Binding Id, Mode=TwoWay, ValidatesOnExceptions=True, ValidatesOnDataErrors=True, NotifyOnValidationError=True}"/> <sdk:DescriptionViewer Grid.Column="2" Grid.Row="1" Description="Id must be greater than 4 and should be greater than 9."/> <sdk:Label Grid.Row="2" Target="{Binding ElementName=NameTextBox}" Margin="3" HorizontalAlignment="Right"/> <TextBox x:Name="NameTextBox" KeyDown="TextBox_KeyDown" Grid.Column="1" Grid.Row="2" Margin="3" MaxLength="10" Text="{Binding Name, Mode=TwoWay, ValidatesOnExceptions=True, ValidatesOnDataErrors=True, NotifyOnValidationError=True}"/> <sdk:DescriptionViewer Grid.Column="2" Grid.Row="2" Description= "Name must not contain spaces and should be 5 characters or less."/> <sdk:ValidationSummary Grid.Row="3" Grid.ColumnSpan="2" Margin="3"/> </Grid> </UserControl>
Partial Public Class MainPage Inherits UserControl Public Sub New() InitializeComponent() LayoutRoot.DataContext = New Product() With {.Id = 10, .Name = "food"} End Sub ' Commits text box values when the user presses ENTER. This makes it ' easier to experiment with different values in the text boxes. Private Sub TextBox_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Input.KeyEventArgs) If e.Key = System.Windows.Input.Key.Enter Then CType(sender, TextBox) _ .GetBindingExpression(TextBox.TextProperty).UpdateSource() End Sub End Class
For a list of the operating systems and browsers that are supported by Silverlight, see Supported Operating Systems and Browsers.

