We have approached it like this:
We have a ValidationProperty class that takes in a RegularExpression that will be used to validate the value (you could use whatever you wanted).
ValidationProperty.cs
public class ValidationProperty
{
#region Constructors
/// <summary>
/// Constructor for property with validation
/// </summary>
/// <param name="regularExpression"></param>
/// <param name="errorMessage"></param>
public ValidationProperty(string regularExpression, string errorMessage)
{
RegularExpression = regularExpression;
ErrorMessage = errorMessage;
IsValid = true;
}
#endregion
#region Properties
/// <summary>
/// Will be true if this property is currently valid
/// </summary>
public bool IsValid { get; private set; }
/// <summary>
/// The value of the Property.
/// </summary>
public object Value
{
get { return val; }
set
{
if (this.Validate(value))//if valid, set it
{
val = value;
}
else//not valid, throw exception
{
throw new ValidationException(ErrorMessage);
}
}
}
private object val;
/// <summary>
/// Holds the regular expression that will accept a vaild value
/// </summary>
public string RegularExpression { get; private set; }
/// <summary>
/// The error message that will be thrown if invalid
/// </summary>
public string ErrorMessage { get; private set; }
#endregion
#region Private Methods
private bool Validate(object myValue)
{
if (myValue != null)//Value has been set, validate it
{
this.IsValid = Regex.Match(myValue.ToString(), this.RegularExpression).Success;
}
else//still valid if it has not been set. Invalidation of items not set needs to be handled in the layer above this one.
{
this.IsValid = true;
}
return this.IsValid;
}
#endregion
}
Here's how we would create a Validation property. Notice how the public member is a string, but privately I am using a 'ValidationProperty.'
public string TaskNumber
{
get { return taskNumber.Value.ToString(); }
set
{
taskNumber.Value = value;
OnPropertyChanged("TaskNumber");
}
}
private ValidationProperty taskNumber;
Now, whenever the value is set, the business layer will validate that it's a valid value. If it's not, it will simply throw a new ValidationException (in the ValidationProperty class). In your xaml, you will need to set NotifyOnValidationError & ValidatesOnExceptions to true.
<TextBox Text="{Binding TaskNumber, Mode=TwoWay, NotifyOnValidationError=True, ValidatesOnExceptions=True}"/>
With this approach, you would probably have a form for creating a new 'User' and each field would valitate each time they set it (I hope that makes sense).
This is the approach that we used to get the validation to be on the business layer. I'm not sure if this is exactly what you're looking for, but I hope it helps.