Let’s say you have a data model of a class that has two fields that are required. One of them is a string, let’s say “Name”, and the other is an int value, let’s say “Age”. And you have to validate these values before you pass them to the data layer to write to the database. How would you do it? Probably something like this (assuming XAML controls are bound to the properties):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
… wanna see how W2C does it?
1 2 3 4
Yeah, I know, we rock. But really this took quite a bit of figuring out. Here’s the components that actually make it work:
- IDataErrorInfo – this is a newish interface that WPF takes advantage of to validate controls once they update their data sources. There’s two methods, string this[string columnName] and Error, both which return either null / empty strings or a message. Most people use these methods to do the custom validation within them, a “if columnName == ‘Name’ && string.isNullOrEmpty(Name)” type of approach which is still kind of tedious, so I did more digging
- DataAnnotationAttributes – also new to .NET, and primarily targeted at ASP.NET Dyanmic Data as well as Silverlight RIA applications, these define those [Required] and [Range] attributes we use (also RegularExpression, DataType, and StringLength), as well as give you a base class to create you own. The Dynamic Data and RIA controls are setup to use these automatically, but not anything else, so there’s one more component…
- DataAnnotationValidator! – This is a group of methods that I borrowed from someone online and modified to use Generics so they work with pretty much any class with properties that you can throw at it. DataAnnotationValidator is setup to enumerate through a class’s properties, look for those Annotation Attributes, and perform the validations if any are found.
This validation action is actually performed by WPF automatically because we’re extending the IDataErrorInfo interface, so any time a bound control has its value changed it’ll check against the DataAnnotationValidator and update the control based on the result.