Collecting all errors of ValidationRules in WPF

Almost all articles on WPF and validation focus first on ValidationRules, and then continue telling you why IDataErrorInfo is better. A few go on and show you how to combine IDataErrorInfo with DataAnnotations.

While these last two are definitely good options, they're a little heavy for a very simple application. In my case: call a server, show the data (about 20 textboxes), send back to the server. Nothing fancy, I'm even databinding to my datacontract (gasp!), although I'm sending back a separate datacontract (with only the changeable properties).

This may go against best-practices, but I feel best-practices differ depending on the complexity of the problem you're trying to solve. In this case, in my opinion, it's okay to do what I'm doing.

I've added validation via ValidationRules. The problem lots of sources will tell you, is that there's no way of aggregating these errors. Collecting these errors can be handy for displaying them, disabling a save-button, etc.

However, there is a way. And a fairly easy one too. Whenever a validation changes (from fail to success or from success to fail), it raises a RoutedEvent: the Validation.Error attached event (if NotifyOnValidationError is set to true).

And what is a characteristic of RoutedEvents? They "bubble up". So you can handle them higher up in the UI tree.

In the control containing your validated controls, add a Validation.Error event handler and you will be able to catch the errors of containing controls. You could handle them like this:

private void Validation_OnError(object sender, ValidationErrorEventArgs e)  
{
    if (e.Action == ValidationErrorEventAction.Added)
        _errors.Add(e.Error);
    else
        _errors.Remove(e.Error);

    SaveButton.IsEnabled = !_errors.Any();
}

Note: if you're using MVVM, you're probably better of using IDataErrorInfo (yes Stefaan, I'm saying you're right ;).