WPF offers some rather good stuff when it comes to applying validation to binding expressions. However it isn’t complete in my opinion and could use some kind of extension to make it even easier and more effective to use in an application.
There are a couple of things I noticed when working with validation in WPF:
- It is not possible to check for binding validation failures. You need to manually check all bound values for validity, even if you have validation rules for them.
- Validation rules are not triggered if the binding value hasn’t been changed. This may sound weird, but if you have a way of checking the validation rules it still doesn’t work because validation rules aren’t triggered when the binding value hasn’t been changed. This results in incorrect behavior.
- The range of validation rules is limited. WPF offers only one validation rule out of the box. This is the ExceptionValidationRule. It is one however that you don’t want to miss, since it allows to catch exceptions that otherwise cause the application to crash.
I created a small framework to resolve these issues, I opted for validating using validation rules instead of the IErrorInfo that others have written about. I did this because I wanted more flexibility, so that I’m able to not only validate rich business objects, but also validate simple bindings.
To resolve the first issue I wrote a decorator which you can use to mark content on a page/window/usercontrol that needs to be validated. The decorator has a Validate() method to validate the content. This will iterate over all the child elements and validate the validation rules. The decorator marks the content as invalid when one of the validation rules fails to validate.
The second feature I implemented on the ValidatedContent decorator is marking controls as required. On the decorator there’s a property to assign a RequiredControlStyle. This is a WPF style that modifies the control and gives the user a visual hint that a control is required. The default style is empty and you need to supply your own by binding the property to a static resource or assign a style in code.
To mark a control as required you use the ValidatedContent.IsRequired attached property. When the control loads the ValidatedContent decorator iterates over its child elements and assigns the RequiredControlStyle to each control that is marked as required.
The last feature that is implemented, is a collection of ErrorMessages. This collection gets filled with all errormessages that might be exposed by failed validationrules.
Microsoft hasn’t included any validationrule implementation, except for the ExceptionValidationRule. In the validation framework I included some more basic validationrules a list of them is provided below:
The last rule adds a property to specify the errormessage to display.
Fixing the validationrule triggers
The second issue that I talked about is somewhat tricky to resolve. This involves some hefty reflection code. First thing I tried was using Validation.GetHasErrors(). Unfortunatly this method doesn’t trigger the validation rules properly and fails to detect errors.
The only way to fix this problem was to retrieve all dependency properties of an element, iterate over them and retrieve the binding with the validation rules for each dependency property. After the validation rules are retrieved it’s a matter of manually triggering the validation rules. This way the errors are properly detected.
Download and more information
For more information on how to change the default behavior of errortemplates: http://www.codeproject.com/KB/WPF/wpfvalidation.aspx
For more information on data validation in WPF 3.5: http://blogs.msdn.com/wpfsdk/archive/2007/10/02/data-validation-in-3-5.aspx
To download the framework: http://www.codeplex.com/wpfvalidation