After looking at Twitter yesterday, we have arrived at another data binding-related feature new in Silverlight 4, namely the support for the IDataErrorInfo interface.
The fact that Silverlight supports this interface now, means we can fully use it to help with the display of validation errors in a data binding scenario. The interface itself is quite simple, as shown below:
public interface IDataErrorInfo
{
string Error { get; }
string this[string columnName] { get; }
}
When we are binding an object of a class that implements the IDataErrorInfo, Silverlight will automatically check each field for validation errors using the indexer. In here, we can write validation code that will check if the specified value is valid and if not, return the error message for that field. Silverlight will then automatically display the error for the field.
I have created a small sample that does exactly that. Being it almost Christmas, I have created a sample where the user can enter his christmas music collection, as shown below.
The type we are binding to is called ChristmasSong. This class implements both the INotifyPropertyChanged and the IDataErrorInfo interfaces. Both have been implemented in the code below. In the indexer, we are checking per column if the entered value is valid. If not, we are returning a message containing the validation error. Note that when we are entering “Last Christmas” by “Wham”, the application will not accept it! (Sorry to all Wham fans )
public class ChristmasSong : IDataErrorInfo, INotifyPropertyChanged
private string title;
private string performedBy;
private TimeSpan duration;
private DateTime published;
private string error;
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(string propertyName)
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
public string Title
get
return title;
set
title = value;
NotifyPropertyChanged("Title");
public string PerformedBy
return performedBy;
performedBy = value;
NotifyPropertyChanged("PerformedBy");
public TimeSpan Duration
return duration;
duration = value;
NotifyPropertyChanged("Duration");
public DateTime Published
return published;
published = value;
NotifyPropertyChanged("Published");
public string Error
get { return error; }
public string this[string columnName]
string error = string.Empty;
switch (columnName)
case "Title":
if(string.IsNullOrEmpty(title))
error = "Title can not be blank";
break;
case "PerformedBy":
if(string.IsNullOrEmpty(performedBy))
error = "The artist should be filled in";
else if(performedBy.Equals("Wham") && title.Equals("Last Christmas"))
error = "You should NOT be entering that song to your collection!";
case "Duration":
if(duration.TotalSeconds > 600)
error = "A song can not be longer than 10 minutes";
case "Published":
if (Published > new DateTime(2010, 1, 1))
error = "You found a song from the future?";
else if (published < new DateTime(1900, 1, 1))
error = "That's a bit too old, isn't it?";
return error;
We can now bind our UI to an instance of this type. Below is the XAML code for the Grid containing the fields. Note especially the data binding expression, where I’m stating the fields should be reporting the error back. For spacing reasons, I only pasted the Title field, the others are similar.
<TextBlock x:Name="TitleTextBlock" Text="Title" Grid.Row="1"
Foreground="Red" HorizontalAlignment="Left" Margin="2"
VerticalAlignment="Center"></TextBlock>
<TextBox x:Name="TitleTextBox" Grid.Row="1" Grid.Column="1" Width="200"
VerticalAlignment="Center" HorizontalAlignment="Left" Margin="2"
Text="{Binding Path=Title, Mode=TwoWay, ValidatesOnDataErrors=True,
NotifyOnValidationError=True}" />
When we are entering data now, the validation will kick in whenever a validation error is encountered.
We can take it one step further though, using the BindingValidationError event, defined on FrameworkElement. This event will trigger whenever a binding error is reported by the binding source, being here the instance of the ChristmasSong class. In this event, we can through the e.Action property check if an error was added or resolved. In this particular code, I have specified that the Submit button will only become enabled when there are no more errors.
private void ChristmasSongGrid_BindingValidationError(object sender,
ValidationErrorEventArgs e)
switch (e.Action)
case ValidationErrorEventAction.Added:
errorsOnPage++;
case ValidationErrorEventAction.Removed:
errorsOnPage--;
if (errorsOnPage == 0)
SubmitButton.IsEnabled = true;
else
SubmitButton.IsEnabled = false;
All this can be seen in action, when we are entering “Last Christmas” by “Wham”!
The sample code can be downloaded here: SLDataErrorInfo.zip (308.96 KB)
Ads by The Lounge
All content is property of www.snowball.be. Nothing on this site can be copied or published elsewhere, unless otherwise stated.
This site is made by Gill Cleeren.
Questions? Opinions? E-mail