With WPF 4.5 you have a new (modern) way of valdiation: the INotifyDataErrorInfo interface (inherited from Silverlight. Thank you little brother, RIP).

This interface is somewhat a combination of the IDataErrorInfo technique and the capacity to raise event of a change on the status of the validation of a property (like the INotifyPropertyChanged interface raise the changement of the value).

It offers several interesting scenarios:

Control the moment of the validation

Allow asynchronous validation on a background thread

Make it easier to invalidate a property when setting another property

To express (a part of) the possibilities offered of this interface I will create a base ValidatableModel class.
The approach is to implement INotifyDataErrorInfo and INotifyPropertyChanged interfaces, validate the entire object at each change on the properties with the DataAnnotation validation attributes.
The error are stored in a dictionary that represent the "validation state" of the model and the validation is ran on background (you can add a Thread.Sleep to see the latency).
The validation is locked and launch on each RaisePropertyChanged().

publicclassUserInput:ValidatableModel{privatestring_userName;privatestring_email;privatestring_repeatEmail;[Required][StringLength(20)]publicstringUserName{get{return_userName;}set{_userName=value;RaisePropertyChanged("UserName");}}[Required][EmailAddress][StringLength(60)]publicstringEmail{get{return_email;}set{_email=value;RaisePropertyChanged("Email");}}[Required][EmailAddress][StringLength(60)][CustomValidation(typeof(UserInput),"SameEmailValidate")]publicstringRepeatEmail{get{return_repeatEmail;}set{_repeatEmail=value;RaisePropertyChanged("RepeatEmail");}}publicstaticValidationResultSameEmailValidate(objectobj,ValidationContextcontext){varuser=(UserInput)context.ObjectInstance;if(user.Email!=user.RepeatEmail){returnnewValidationResult("The emails are not equal",newList<string>{"Email","RepeatEmail"});}returnValidationResult.Success;}}

One last thing is to enable this validation on the bindings with the ValidatesOnNotifyDataErrors property.

You can also imagine to launch the validate only when the save button is clicked or use a Reactive Extensions (RX) query with the Throttle method to limit the time between two validation (for exemple validate max once per sencond).