Jerry Nixon on Windows: Mango Sample: Data Validation

Wednesday, November 23, 2011

Mango Sample: Data Validation

imageWhoa! I am getting a lot of questions on data validation. This warrants an article. Of course, we have many choices. Some are prescriptive, some are simple, and some are just not reliable.

For now, I will just limit data entry to valid numbers. That doesn’t mean Char.IsNumeric. Commas and periods are valid. I also have to remember valid keys like shift, backspace, and tab.

Option 1: KeyDown

This is a good approach. It requires a lot of code. But, it is a well-proven strategy. All you do is evaluate the user’s keys and cancel the invalid ones. Your XAML might be like this:


Our code-behind could simple be:


In the code above, see where I call AddHandler()? This is important because not all keystrokes are bubbled to KeyDown. AddHandler works around this. And see e.Handled? Setting that to false cancels the keystroke. The logic in ParseDouble() is here.

Option 2: InputScope

InputScope controls the keyboard configuration. This should be part of other approachs. But, on its own, it’s problematic since it does not prevent users from entering (or pasting) invalid data.
InputScope is awfully easy to handle in XAML:


Option 3: BindingValidationError

Silverlight’s Binding Validation is another option. A property’s setter throws an exception if value is invalid. The binding catches this and raises BindingValidationError. You can handle this event to display an error message to the user.


Our XAML changes like this:


In the code above, see BindingValidationError attached to the StackPanel? Attaching to the StackPanel let’s me handle more than one TextBox. I would have attached to the TextBox. But, also notice ValidatesOnExceptions (by-passes the need to use ExceptionValidationRule explicitly) and NotifyOnValidationError. These are necessary.

With this code-behind:

image image

In the code above, we have a workaround? WPF has UpdateSourceTrigger=PropertyChanged (OnPropertyChanged in Windows Forms) that causes the underlying object to update as the user changes any part of the property’s value. Windows Phone does not support this. But this code makes it work. To validate as uses type, we need this. Otherwise we validate on Blur.


In the code above, we’re handling the error. The framework has “caught” the error for us, and bubbled it here. Using e.Action we can detect the new error. Using e.OriginalSource we can detect the specific TextBox (or any control) that caused it. Then, show the user the message.


In the code above, this is our sample DTO. It’s simple, eh? And, as you can see, all we do is raise an exception in the setter. No special interface. No special base class. No special exception. This is truly a great option for Silverlight developers.

Option 4: ExceptionValidationRule

Validation Rules (using ExceptionValidationRule) allow you to put rules outside the DTO and reuse them across controls. The rule itself is a custom class you use to determine validity.
Your XAML would look like this:


However, these are not supported in Windows Phone. Why even mention them? These are tools for WPF developers. It’s worth knowing what your limits are.

Option 5: Data Annotations

Data Annotations are custom attributes that decorate your classes and properties with things like Required, Range, Expressions, and Custom code. These are a big deal with ASP.Net & EF4.

Your Classes would look like this:


However, these are not supported in Windows Phone. Why mention them? These are very compelling validation tools. It’s worth knowing what your limits are.

Option 6: IDataErrorInfo

Remember BindingValidationError (Option 2)? Maybe you don’t want to throw errors. This interface is your answer. IDataErrorInfo is an extension using an error list instead exceptions.

The UI result is identical to Option 2:


The XAML is identical to Option 2:


The code-behind is not the same (but close):


In the code above, look at the setter. Where, in Option 2 we threw an exception when the parse failed, here we add to the error list (in our case a dictionary). You might be wondering about that Error property throwing a NotImplementedException? It turns out the interface includes that as a convenience to the developer (no thanks) and is not used by the Binding engine.

Option 7: INotifyDataErrorInfo

Here’s what MSDN says: In general, new entity classes for Silverlight should implement INotifyDataErrorInfo for the added flexibility instead of implementing IDataErrorInfo.

Well isn’t that a fine howdy-do? We go through all this work to use Data Binding validation only to be told we should use INotifyDataError. Then we go through all that work only to be told we should be using INotifyDataErrorInfo. Good news! This is it – the prescribed approach.

Why is this worthwhile? Well, let’s consider how IDataErrorInfo works. Right after the data value is set, the error list is queried. This expects the validation to nearly immediate. What if your validation took some time? You need an event, you need INotifyDataErrorInfo.

The UI looks the same (exactly):


The XAML looks the same (exactly):


Even the code-behind looks almost the same:


In the code above, there are only a few changes from the IDataErrorInfo implementation. Specifically, the presence of the ErrorsChanged event. This alerts the UI to “come look again!” for validation errors. Using this approach allows for validation to take as long as it needs – like calling to a service – using an async call.
Please note: I did not implement an async operation in my sample. For more on Windows Phone async operations, look at this article. For more information in calling out to a service, look at this article.

Option 8: Custom

How would this list be complete without a Custom solution? What if you are paid by the hour and want to build your own from scratch? Can you do that, too? The answer is no. There is no way to build custom validation on the Windows Phone platform. Ha! Just kidding, of course there is. But why? It doesn’t matter. Let’s do it!

Here’s the XAML:


In this sample we’re using attached properties – attached to the error label. The format and the textbox are specified. The code-behind does the rest – checking the value, adding the error message, changing the background color.

Here’s our code-behind:


In the code above, see the Setup() method? This is called by both properties because the they could be set in any order. But this is where we attach to the TextChanged event. In that handler, we test the format, and update the UI based on the result. And this is quite generic. I like it.

As an aside, in a WPF project we actually added a custom behavior to the TextBox control. This is yet another option for you. Actually, the sky is pretty much the limit for your custom solution.


WPF and Silverlight developers have a few more validation options than Windows Phone developer. Those are important to know – saving you time hunting. However, some techniques available to Windows Phone developers vary in support. Overall, the two best are KeyDown and INotifyDataErrorInfo. Each is well supported, proven, and useful. But if they do not fit the bill, you can build a custom solution.

Best of luck!