Home
Search
 
What's New
Index
Books
Links
Q & A
Newsletter
Banners
 
Feedback
Tip Jar
 
C# Helper...
 
XML RSS Feed
Follow VBHelper on Twitter
 
 
 
MSDN Visual Basic Community
 
 
 
 
 
TitleMake an ExtenderProvider to validate TextBoxes by using a regular expression in VB .NET
DescriptionThis example shows how to make an ExtenderProvider to validate TextBoxes by using a regular expression in VB .NET. The provider catches its clients' Validating events and verifies that the values satisfy the expression.
KeywordsRegex, regular expression, ExtenderProvider, validation, validate
CategoriesSoftware Engineering, Controls, VB.NET
 
See Tutorial: Introduction to ExtenderProviders in VB .NET for an overview of creating ExtenderProviders.

This provider stores RegexPattern and RegexMessage values for each of its clients in its private RegexInfo class. It stores RegexInfo objects in its m_RegexInfo hashtable. It also adds an event handler to catch each client control's Validating event.

When that event fires, the provider's ValidateTextBox subroutine determines whether the client TextBox contains a value that satisfies the regular expression stored in RegexPattern. If the TextBox doesn't satisfy the expression, it assigns an error to the TextBox using the provider's embedded ErrorProvider component.

The GetRegexInfo helper function returns a control's RegexInfo object or a default object it the control doesn't have an entry.

The AddOrRemoveIfNecessary helper routine compares a RegexInfo object to a default object. If the object has the default values, then the routine ensures that it is removed from the m_RegexInfo hashtable. If the object does not hold the default values, then the routine ensures that it is in the hashtable.

Finally, to help the program decide whether it is safe to exit, the provider includes a HasError function. This function validates all of the registered client controls to display errors for any that fail to satisfy their regular expressions. It then moves focus to the one with the smallest TabIndex value and displays that control's error message in a message box.

 
Imports System.ComponentModel
Imports System.Text.RegularExpressions

<ToolboxBitmap(GetType(RegexProvider), _
    "regex_provider.bmp"), _
 ProvideProperty("RegexPattern", GetType(TextBox)), _
 ProvideProperty("RegexMessage", GetType(TextBox))> _
Public Class RegexProvider
    Inherits System.ComponentModel.Component
    Implements IExtenderProvider

... Component Designer generated code ...

    ' Information about a control's range.
    Private Class RegexInfo
        Public RegexPattern As String
        Public RegexMessage As String

        Public Sub New()
            RegexPattern = ""
            RegexMessage = ""
        End Sub

        ' Return True if this object represents no range.
        Public Function IsDefault() As Boolean
            Return (RegexPattern.Length = 0) AndAlso _
                   (RegexMessage.Length = 0)
        End Function
    End Class

    ' The information about fields with ranges.
    Private m_RegexInfo As New Hashtable

    Private m_Enabled As Boolean = True
    <Category("Behavior"), _
     DefaultValue(True)> _
    Public Property Enabled() As Boolean
        Get
            Return m_Enabled
        End Get
        Set(ByVal Value As Boolean)
            m_Enabled = Value
        End Set
    End Property

    ' We can extend TextBoxes.
    Public Function CanExtend(ByVal client_control As _
        Object) As Boolean Implements _
        IExtenderProvider.CanExtend
        Return (TypeOf client_control Is TextBox)
    End Function

    ' Return this control's error message.
    <Category("Validation"), _
     DefaultValue("")> _
    Public Function GetRegexPattern(ByVal client_control As _
        TextBox) As String
        Return GetRegexInfo(client_control).RegexPattern
    End Function

    ' Set this control's error message.
    <Category("Validation"), _
     DefaultValue("")> _
    Public Sub SetRegexPattern(ByVal client_control As _
        TextBox, ByVal error_message As String)
        ' Get this control's range info.
        Dim regex_info As RegexInfo = _
            GetRegexInfo(client_control)

        ' Set the new minimum value.
        regex_info.RegexPattern = error_message

        ' Add or remove the RegexInfo if necessary.
        AddOrRemoveIfNecessary(client_control, regex_info)
    End Sub

    ' Return this control's error message.
    <Category("Validation"), _
     DefaultValue("")> _
    Public Function GetRegexMessage(ByVal client_control As _
        TextBox) As String
        Return GetRegexInfo(client_control).RegexMessage
    End Function

    ' Set this control's error message.
    <Category("Validation"), _
     DefaultValue("")> _
    Public Sub SetRegexMessage(ByVal client_control As _
        TextBox, ByVal error_message As String)
        ' Get this control's range info.
        Dim regex_info As RegexInfo = _
            GetRegexInfo(client_control)

        ' Set the new minimum value.
        regex_info.RegexMessage = error_message

        ' Add or remove the RegexInfo if necessary.
        AddOrRemoveIfNecessary(client_control, regex_info)
    End Sub

    ' A client is validating. See if it is blank.
    Private Sub Client_Validating(ByVal sender As Object, _
        ByVal e As System.ComponentModel.CancelEventArgs)
        If Not m_Enabled Then Exit Sub
        ValidateTextBox(DirectCast(sender, TextBox))
    End Sub

    ' Validate the TextBox.
    Private Sub ValidateTextBox(ByVal client_control As _
        TextBox)
        ' Get the control's text.
        Dim client_text As String = client_control.Text
        Dim regex_info As RegexInfo = _
            GetRegexInfo(client_control)

        ' See if the text satisfies the regular expression.
        If Regex.IsMatch(client_text, _
            regex_info.RegexPattern) Then
            ' It matches.
            errBadMatch.SetError(client_control, "")
        Else
            ' It doesn't match.
            errBadMatch.SetError(client_control, _
                regex_info.RegexMessage)
        End If
    End Sub

    ' Return this control's RegexInfo.
    Private Function GetRegexInfo(ByVal client_control As _
        Control) As RegexInfo
        ' See if we have RegexInfo for this control.
        If m_RegexInfo.Contains(client_control) Then
            ' We have RegexInfo for this control. Return it.
            Return DirectCast(m_RegexInfo(client_control), _
                RegexInfo)
        Else
            ' We do not have RegexInfo for this control.
            ' Return a new default RegexInfo.
            Return New RegexInfo
        End If
    End Function

    ' Add or remove this RegexInfo if necessary.
    Private Sub AddOrRemoveIfNecessary(ByVal client_control _
        As Control, ByVal regex_info As RegexInfo)
        ' See if the RegexInfo should be present but is not,
        ' or should not be present but is.
        If regex_info.IsDefault <> Not _
            m_RegexInfo.Contains(client_control) Then
            If regex_info.IsDefault Then
                ' The RegexInfo should not be present but
                ' is.
                m_RegexInfo.Remove(client_control)
                RemoveHandler client_control.Validating, _
                    AddressOf Client_Validating
            Else
                ' The RegexInfo should be present but is
                ' not.
                m_RegexInfo.Add(client_control, regex_info)
                AddHandler client_control.Validating, _
                    AddressOf Client_Validating
            End If
        End If
    End Sub

    ' If some control has an error, display its error
    ' message,
    ' set focus to it, and return True. If all controls are
    ' okay, then return False.
    Public Function HasError() As Boolean
        If Not m_Enabled Then Return False

        ' Make sure all controls have been validated.
        Dim first_text_box As TextBox = Nothing
        Dim first_tab_index As Integer = Integer.MaxValue
        For Each text_box As TextBox In m_RegexInfo.Keys
            ' Validate the TextBox.
            ValidateTextBox(text_box)

            ' See if this is the first in the tab order so
            ' far.
            If errBadMatch.GetError(text_box).Length > 0 _
                Then
                If text_box.TabIndex < first_tab_index Then
                    first_text_box = text_box
                    first_tab_index = text_box.TabIndex
                End If
            End If
        Next text_box

        ' See if any control has an error.
        If Not (first_text_box Is Nothing) Then
            first_text_box.Focus()
            MessageBox.Show(errBadMatch.GetError(first_text_box))
            Return True
        End If

        Return False
    End Function
End Class
 
At design time, you set the properties for TextBoxes that you want to be required. The main program doesn't need to use any code to validate TextBoxes.

If you want to ensure that all TextBoxes are valid, call the HasError function in the form's Closing event handler to see if it is safe to close the form.

 
Private Sub Form1_Closing(ByVal sender As Object, ByVal e _
    As System.ComponentModel.CancelEventArgs) Handles _
    MyBase.Closing
    e.Cancel = RegexProvider1.HasError()
End Sub

Private Sub btnOk_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles btnOk.Click
    Me.Close()
End Sub

Private Sub btnCancel_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles btnCancel.Click
    RegexProvider1.Enabled = False
    Me.Close()
End Sub
 
 
Copyright © 1997-2010 Rocky Mountain Computer Consulting, Inc.   All rights reserved.
  Updated