Daniel Cazzulino's Blog : Automatic input validation in WPF with data binding and Enterprise Library Validation Application Block

Automatic input validation in WPF with data binding and Enterprise Library Validation Application Block

WPF provides validation infrastructure for databinding scenarios through ValidationRule objects. Only one built-in rule is provided, and you’re expected to write most of these yourself. The way they work is by assigning one or more explicit rules to a binding:

<TextBox ...>  
  <TextBox.Text>  
    <Binding .>  
      <Binding.ValidationRules>  
        <local:JpgValidationRule/>   
      </Binding.ValidationRules>  
    </Binding>  
  </TextBox.Text>  
</TextBox> 

[Example from Adam Nathan’s excelent book on WPF]

Note that the syntax is much more involved than the simple non-validating binding:

<TextBox Text="{Binding ...}">  
</TextBox> 

Another consequence of the provided support is that even if you reuse the data context (i.e. you provide more than one screen that binds to a given object type, say “Customer” object) in more than one editing scenario, you will need to duplicate the validators and make sure you keep them in sync. Also, you will typically be performing the same validation again in the object itself (i.e. the above binding probably sets a “Photo” string property), so you either take a dependency on WPF from your entities project just to call the same validation rules, or you duplicate the code to perform the validation (or you make your rules just expose a WPF interface over the same objects). In any case, there’s no straight-forward way to reuse the logic, and maintaining the XAML and entities internal validation rules in sync is far from ideal.

The Microsoft Enterprise Library Validation Block (EntLib VAB) solves this problem by providing attribute (or configuration) driven rules that you can validate on the UI as well as on your entities. For example:

				public
				class
				Customer
				
				{
  privatestring firstName;

  [StringLengthValidator(1, RangeBoundaryType.Inclusive, 0, RangeBoundaryType.Ignore)]
  [NotNullValidator]
  publicstring FirstName

The code above specifies that the FirstName property must be a non-null, non-empty string. You could very easily create a custom validation rule such as NotNullOrEmptyValidator ;), but you get the idea.

EntLib VAB provides integration with WinForms and ASP.NET validation architectures, but not for WPF. Up to now, that is ;).

I’ve been working for the past few days on getting a kick-ass integration with WPF. It wasn’t easy, and I found a couple not-so-nice things in the way, but I finally got the following working flawlessly (and without any hacks):

<Window ... xmlns:v="http://www.codeplex.com/entlibcontrib">
  <Grid>
    ...
    <Label Content="First Name:"/>
    <TextBox Text="{v:ValidationBinding FirstName}" .../>
    ...
    <TextBox Text="{v:ValidationBinding Address.USState}" .../>
    ...
  </Grid>
</Window>

This sample markup and the class above are part of a sample available with the download.

You can now do a simple search&replace of Binding with v:ValidationBinding and that’s it. If your data context objects (or entities) provide validation attributes, they will get automatically applied to the binding, and all the WPF-specific handling on the UI for showing the errors and styling the elements with errors will be available to you for free.

The ValidationBinding is nothing more than a MarkupExtension that acts as a decorator for a Binding. Hence, the full data binding behavior is preserved, as I’m basically returning from my extension the result of evaluating the binding I’m decorating (prior to attaching my validation rule). From that point on, it’s plain built-in validation rules and a few creative tricks to get around EntLib VAB’s a bit weird “integration” model. It may be interesting to look for someone looking to implement their own markup extensions. In order to allow for the drop-in replacement scenario with the Binding class, I also expose all of the public properties of a binding, so that if you’re using any of them, you get full fidelity behavior as they are all just pass-through getters/setters to the inner instance of the binding I’m constructing.

I’ve contributed this code to the EntLib Contrib project as part the Standalone Validation Application Block, which is a version of the VAB that doesn’t depend on configuration at all. I’ve written about why XAML makes System.Configuration and Enterprise Library Configuration obsolete and why we need an EntLib Standalone Validation Application Block before. I may integrate this with the official EntLib 3.1, but it’s not a high priority for me as I don’t believe we need all the System.Configuration/ObjectBuilder baggage just for validation. If there’s enough demand for it through the project discussions, though, I’m sure someone (maybe myself?) will get it done eventually.

Go get the release, and enjoy developing apps with full input validation and data binding in (almost) pure markup :

/kzu

/kzu dev↻d