The bulk of validation work is done in the default indexer property. It's called by controls that are bound to object properties as data changes to see if a particular bound property is valid or not. The Person class above has two basic properties in it including Name and Age that need to be validated. This can be done in the default indexer property added into the class as a result of implementing IDataErrorInfo as in Listing 2.
public string this[string propertyName]
{
get
{
_Errors = null;
switch(propertyName)
{
case "Name":
if (string.IsNullOrEmpty(Name))
{
_Errors = _ErrorsText;
return "Name cannot be empty!";
}
break;
case "Age":
if (Age < 1)
{
_Errors = _ErrorsText;
return "Age must be greater than zero.";
}
break;
}
return null;
}
}
The validation operations performed in the default indexer property are quite simple in this example. First, a switch statement checks which property needs to be validated. From there, each case statement is used to perform validation logic including checking that the Name property isn't null or empty and that the Age property has a value greater than 0. What's nice about this approach is that the validation logic is put in one place and in more real-world situations the logic can even be moved to an external validation object that provides some re-useable methods to check for null strings, check string lengths, validate numeric ranges, etc.
The end result of implementing the IDataErrorInfo interface is that controls bound to properties can check to see if data is valid or not and then display an error message as appropriate. This is done by adding the
ValidatesOnDataErrors property to the data binding as shown next:
<TextBox Text="{Binding Name,Mode=TwoWay,ValidatesOnDataErrors=true}"
Height="23"
Width="120"
HorizontalAlignment="Left"
VerticalAlignment="Top" />
Figure 1 shows an example of a TextBox control bound to a property containing invalid data. The error message displayed in red is generated automatically as the control checks the default indexer property from IDataErrorInfo of the bound object to verify if a given property is valid or not. This type of validation functionality exists in many controls throughout Silverlight such as TextBox, DataForm, DataGrid, etc.
The downside of the IDataErrorInfo interface is that it doesn't provide a way to perform asynchronous validation. In some situations you may need to call back to a server to check that a user ID or email address is unique within the system or that a tax code matches an existing code stored in a database. IDataErrorInfo doesn't support this type of scenario directly. If you want to get a jump on the process of implementing INotifyDataErrorInfo check out the code associated with this article which is available here.



