|
Welcome,
Guest
|
|
TOPIC: Regex Validation in WPF
Regex Validation in WPF 10 Feb 2010 15:29 #272
|
Introduction
This article demonstrates how regular expressions can be used to validate user input in a Windows Presentation Foundation (WPF) application. The technique presented herein provides two ways for a developer to validate the text of a TextBox via regular expressions: explicitly adding a ValidationRule-derived object to the ValidationRules of a Binding, or simply using attached properties of a static service provider class. Full Size Image Background WPF provides an approach to input validation which is very different from the way that validation was performed in WinForms and ASP.NET. This article assumes that the reader is familiar with the fundamentals of WPF validation. If you are not yet familiar with validation in WPF,. This page in the SDK is also very informative. The general idea behind input validation in WPF involves the abstract ValidationRule class. Classes which derive from ValidationRule must override the Validate method to perform custom validation logic and return a value which indicates whether the input value is valid or not. Instances of the ValidationRule-derived classes can be added to a Binding�s ValidationRules collection. When it comes time for the bound value to be validated, all of the ValidationRule-derived objects will be queried to see if the input value is valid. RegexValidationRule My goal was to create a reusable means of validating user input via regular expressions. I implemented this by creating the RegexValidationRule class, which derives from ValidationRule, and executing a Regex in its Validate override. The RegexValidationRule is designed to validate the Text property of a TextBox. The XAML below shows how to use this class: <TextBox Name="txtProductCode"> The Binding and RegexValidationRule created above in XAML can be created in the code-behind, as seen here: Binding binding = new Binding();How it works The rest of this article explains how the RegexValidationRule and RegexValidator work. You do not need to read this section in order to use those classes in your applications. The RegexValidationRule is very simple. Below is a stripped-down version of the class: public class RegexValidationRule : ValidationRuleThe Validate method (which is inherited from ValidationRule) simply calls the static IsMatch method of the Regex class to perform the validation. If the input value does not match the regular expression stored in the RegexText property, a ValidationResult is returned which indicates that the value is invalid and supplies an error message. The error message is retrieved from the ErrorMessage property. If the input value is valid, the ValidResult property is returned. That property returns a singleton instance of ValidationResult, so using it to indicate success allows us to avoid fragmenting the managed heap with redundant ValidationResult instances that all express the same thing (�the value is valid�). The RegexValidator class is more complicated. First, let�s see how the class is declared: public static class RegexValidatorSince it is a static class, it can never be instantiated and all of its members must be static. This makes sense, because this class is a service provider and all of its functionality is exposed via attached properties. There is no reason to instantiate the class. Next, we will examine the implementation of its attached properties: /// <summary>Those attached properties are following the required convention of having public static Get/Set methods to associate a property value with a DependencyObject (in this case, it only works with the TextBox class). The attached properties are registered in a static constructor: static RegexValidator()Notice that when the properties are registered, a callback method is supplied in the UIPropertyMetadata argument. That callback is invoked whenever the value of one of RegexValidator�s attached properties is modified for a TextBox. That callback method is implemented like this /// <summary>You might be wondering why I bothered using a callback to call the VerifyRegexValidationRule method, instead of just calling that method from within the static Set methods created for the attached properties. It might seem that this approach would work just fine, and be simpler: // This is not how it works!This approach would work if the value of the ErrorMessage property was always set by calling RegexValidator.SetErrorMessage for a TextBox. However, it is entirely possible to set the ErrorMessage attached property (or any other attached property) for a TextBox by directly calling SetValue on the TextBox itself, just like the SetErrorMessage method does. In that situation, the call to VerifyRegexValidationRule would not occur and the TextBox�s Text property binding would never have a RegexValidationRule added to its ValidationRules collection. By using the callback method supplied when registering the attached property, we can rest assured that whenever the attached property value is modified for a TextBox, our callback will call VerifyRegexValidationRule. Now, it is time to examine what the VerifyRegexValidationRule method does. Remember, this method is called whenever the value of a RegexValidator attached property is modified. /// <summary>This method attempts to retrieve a RegexValidationRule which is to be used for the specified TextBox�s Text property binding. If it gets a reference to one, it transfers property values to that object. Notice that the actual values for the RegexValidationRule properties are stored by the TextBox as attached properties. When working with attached properties, it is important to keep in mind that the value of those properties are stored by the object to which they are applied, not by the class/object which exposes the attached properties. At this point, it is necessary to examine how the GetRegexValidationRuleForTextBox method works. This method is responsible for creating or retrieving a RegexValidationRule object for a given TextBox. /// <summary>That method gets a reference to the BindingExpression associated with the TextBox�s Text property. It then retrieves a reference to the Binding which owns the expression, and iterates the Binding�s ValidationRules collection looking for a RegexValidationRule. If it cannot find one, it will create a new instance and add it to the ValidationRules collection. If it finds more than one RegexValidationRule, it will throw an exception, because there is no way to know which one should be returned. This attachment is hidden for guests. Please log in or register to see it. This attachment is hidden for guests. Please log in or register to see it.
Attachments:
|
|
|
|
|
Moderators: mnjon
Time to create page: 1.11 seconds







