January 17, 2021
Hot Topics:

Creating a Custom Control and Custom UITypeEditor in VB - Part 1

  • By Paul Kimmel
  • Send Email »
  • More Articles »

Small, incremental changes to existing controls can be the best way to extend .NET. Small changes are easy to implement and test and can add real value. Incremental changes provide variety, and create an environment where you are layering new behavior on established controls.

In this part of a two-part article, I will be demonstrating how to marry the power of regular expressions to a WinForms TextBox. The regular expression will play the role of input validator. Rolling validation into the TextBox is an example of a small yet valid change. In Part 2 of this article, I will show you how to complement the Regular Expression TextBox by adding a custom type editor. The editor—a UITypeEditor—will permit you to verify at design time that the regular expression is syntactically correct.

Let's get started on the RegexTextBox.

Implementing a Custom Control

In keeping with our small, incremental change theme, I defined a custom TextBox that inherits from the existing System.Windows.Forms.TextBox control. The new TextBox is named RegexTextBox. I added an Expression property that is designed to contain a regular expression, and I provided an overridden implementation of the inherited OnValidating method. At runtime, when the TextBox.Text property is validated, my new method is called. The new method compares the Text property to the regular expression property (Expression), if one is provided. If the Text does not match the rule defined by the expression, the user is notified; that is, validation fails. Listing 1 contains the source code for the RegexTextBox control. (The class module is part of a class library. In my code I named the class library CustomControls, but you can name it anything you'd like.)

Listing 1: A custom TextBox that validates the Text property against a Regular Expression.

1:  Public Class RegexTextBox
2:    Inherits TextBox
4:    Private FExpression As String
6:    Public Property Expression() As String
7:    Get
8:      Return FExpression
9:    End Get
10:   Set(ByVal Value As String)
11:     FExpression = Value
12:   End Set
13:   End Property
15:   Protected Overrides Sub OnValidating( _
16:     ByVal e As CancelEventArgs)
17:     If (FExpression = String.Empty OrElse _
18:       Regex.IsMatch(Text, FExpression) OrElse _
19:       AcceptMismatch()) Then
20:       MyBase.OnValidating(e)
21:     Else
22:       e.Cancel = True
23:     End If
24:   End Sub
26:   Private Function AcceptMismatch() As Boolean
27:     Dim Message As String = String.Format( _
28:       "Text {0} does not match expression {1}", _
29:       Text, FExpression)
31:     Return MessageBox.Show(Message, "Validating", _
32:       MessageBoxButtons.OKCancel, MessageBoxIcon.Error) = _
33:       DialogResult.OK
34:   End Function
36: End Class

The Expression property returns and assigns the value of the associated field FExpression. Nothing too radical here, so it is easy to test. The work happens in the OnValidating method. OnValidating tests to determine whether the Expression is empty, the expression matches, or the user wants to accept a bad expression. If any of these conditions is true, the base—MyBase.OnValidating—method is called on line 20. If any of these conditions fail, Cancel is set to True on line 22 and navigation to the next control doesn't happen. The user has to resolve the invalid text or explicitly agree to accept it.

The OrElse condition is used to provide logic short-circuiting. For example, we don't want AcceptMismatch to be called—see lines 26 through 34—unless the Expression is not empty and the Regex.IsMatch test fails. If we use plain old Or, we get the AcceptMismatch dialog every time, which of course is a logic error. The extra, short-circuited OrElse operator was a compromise between Microsoft's desire to tighten up Boolean evaluations and a VB developer's not wanting modified logic behavior (although who these VB developers were is unknown).

Finally, AcceptMistach displays a message box that informs the user that the input Text failed validation. Clicking OK indicates that this is an acceptable state of affairs; clicking Cancel indicates that the user wants to try again.

Page 1 of 2

This article was originally published on January 23, 2003

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date