
Live Sample: http://silverlight.adefwebserver.com/RIATasks2ABValidation/RIATasksWeb/
There are many types of Silverlight Validation. This covers the most basic type, validating that the data entered matches the underlying type. In this example we will validate a Date Field.

We will start of with the Creating Multiple Dynamic View Models using the Tab Control project.

We add a DueDate field to the Tasks table that is nullable.

We will alter the View so that it has a “Due Date” field and permits these operations:
- Indicates when a valid date is not entered
- Allows you to not enter a date at all
The Validation Handler “Helper Class”
We will first add a helper class created by John Papa:
using System;
using System.Collections.Generic;
using System.Windows.Input;
// From http://johnpapa.net/silverlight/enabling-validation-in-silverlight-4-with-idataerrorinfo/
namespace RIATasks
{
public class ValidationHandler
{
private Dictionary<string, string> BrokenRules { get; set; }
public ValidationHandler()
{
BrokenRules = new Dictionary<string, string>();
}
public string this[string property]
{
get
{
return this.BrokenRules[property];
}
}
public bool BrokenRuleExists(string property)
{
return BrokenRules.ContainsKey(property);
}
public bool ValidateRule(string property, string message, Func<bool> ruleCheck)
{
if (!ruleCheck())
{
this.BrokenRules.Add(property, message);
return false;
}
else
{
RemoveBrokenRule(property);
return true;
}
}
public void RemoveBrokenRule(string property)
{
if (this.BrokenRules.ContainsKey(property))
{
this.BrokenRules.Remove(property);
}
}
}
}
Here are the steps to consume the class:

- Specify the IDataErrorInfo interface
- Instantiate the ValidationHandler class
Implement the IDataErrorInfo with code that will use the ValidationHandler
#region Error Validation
public string Error
{
get { return null; }
}
public string this[string columnName]
{
get
{
if (this.validationHandler.BrokenRuleExists(columnName))
{
return this.validationHandler[columnName];
}
else
{
return null;
}
}
}
#endregion
Create a property for DueDate that is a string, it will display, and save any values to the DueDate property that is in the Task object (I got this technique from Richard Waddell).
The reason we do this is so that the user can enter anything in the View and the binding will still work. If we set the binding to bind directly to the DueDate property that is in the Task object, we would not have access to the values if the user does not put in a valid date.
This would make it hard to provide the user a smooth “experience” for fixing their errors.
#region DueDate
private string _DueDate = null;
public string DueDate
{
get
{
// The first time this is called DueDate will be null
// set DueDate to _CurrentTask.DueDate
if (_DueDate == null && (_CurrentTask.DueDate.HasValue))
{
return _CurrentTask.DueDate.Value.ToShortDateString();
}
else
{
// In all other situations return DueDate
return _DueDate;
}
}
set
{
if (_DueDate == value)
{
return;
}
var dateOut = new DateTime();
bool IsADate = (DateTime.TryParse(value, out dateOut) == true);
// If value is not empty it must be a date
bool valid = validationHandler.ValidateRule(
"DueDate", "Must be a valid date",
() => ((value == "") || (value != "" && IsADate)));
if (valid)
{
// Assign value to CurrentTask.DueDate
if (IsADate)
{
CurrentTask.DueDate = Convert.ToDateTime(value);
}
else
{
CurrentTask.DueDate = null;
}
}
_DueDate = value;
this.NotifyPropertyChanged("DueDate");
}
}
#endregion

The last step, to make it show the red box around the TextBox when there is an error, is to add ValidatesOnDataErrors=True to the binding on the TextBox.
Download
You can download the code at this link:
http://silverlight.adefwebserver.com/RIATasks2ABValidation/RIATasks2ABValidation.zip