Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Simple Validator in Windows Presentation Foundation

0.00/5 (No votes)
23 Oct 2009 1  
Attach simple validator to validate controls

Introduction

There are plenty of articles about WPF and validation rules, but this article will show you a basic implementation of validation rules you can attach to textboxes to provide quick and simple validation based on specified types.

Background

This article will not go into detail of the WPF validation rule feature but will try to explain the general workings. The SimpleValidator is an attached behaviour that can be attached to a TextBox control (possibly other controls later) with a specific type you wish to validate. There are three (3) other optional properties you can use to set the upper bound and lower bound of number types or to specify that the value cannot be empty. Let's see some usages.

Using the Code

There is very little to explain about using the code for it is relatively simple and straight forward. Say we have a TextBox and wish that only numbers (Double) values will be valid. We need to proceed to bind (validation only works on data-bound controls) the Text property to our code-behind (or ViewModel) text. Setting the UpdateSourceTrigger to PropertyChanged ensures that validation happens on every keystroke.

Now we use the attached property to set the type we wish to use (i.e. Double):

<TextBox Text="{Binding BackingText, UpdateSourceTrigger=PropertyChanged}" 
	validator:SimpleValidator.ValidationType="{x:Type system:Double}" />

Remembering that system namespace can be declared as follows:

xmlns:system="clr-namespace:System;assembly=mscorlib" 

To set an upper bound and lower bound to the validation, we simply use as follows:

<TextBox Text="{Binding BackingText, UpdateSourceTrigger=PropertyChanged}" 
	validator:SimpleValidator.UpperRange="20" 
	validator:SimpleValidator.LowerRange="5" 
	validator:SimpleValidator.ValidationType="{x:Type system:Double}" />

This will cause our TextBox to only accept numbers (Double) between the range of five (5) and twenty (20) inclusive. All other values and characters will be rejected. Finally, using the NoEmptyValue property will reject any string value that is empty (after stripping away leading and trailing empty spaces).

<TextBox Text="{Binding Text, UpdateSourceTrigger=PropertyChanged}" 
	validator:SimpleValidator.NoEmptyValue="True" />

How It Works

I will try to briefly describe the workings for those that are curious, but from examining the source code, it's pretty straight forward. The key point of the features is here:

// When the element has loaded.
element.Loaded += (s, e) =>
    {
        // Create a new validator
        var validation = new SimpleValidator(GetValidationType(obj), 
		GetUpperRange(obj), GetLowerRange(obj), GetNoEmptyValue(obj));
        // Get the binding expression for the textbox property
        Binding binding = BindingOperations.GetBinding(obj, TextBox.TextProperty);
        // If not null and doesn't already contain the validator, then add it.
        if (binding != null)
            if (!binding.ValidationRules.Contains(validation))
                binding.ValidationRules.Add(validation);
    };

Basically what happens is when the element is loaded (so that all the bindings are in place), we will create a new instance of our validation rule class and send in the rules we need to validate. We then get the binding from the element's Text dependency property (could be others later on) and add the new validation rule class to it if it doesn't already exist (to avoid multiplicity).

Feedback

This is my first article and any feedback would be greatly welcomed. Please send me any improvement suggestions on how to get this to work for controls other than TextBox.

History

  • 23rd October, 2009: Initial post

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here