65.9K
CodeProject 正在变化。 阅读更多。
Home

使用正则表达式和 ErrorProvider 进行动态验证

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (4投票s)

2008年8月9日

CPOL

3分钟阅读

viewsIcon

44179

downloadIcon

388

在本文中,我们将介绍如何通过定义的验证类型和正则表达式进行动态数据验证。

Snapshot1.GIF

引言

当你在表单中从用户接收数据时,你可能需要过滤和验证一些编辑控件,以防止输入不合理的数据。 例如,年龄字段:在这些字段中,用户输入了诸如“a”之类的字符。 你必须控制该字段的数据,无论是在插入数据时还是在key_press()事件中。

背景

现在想象你有一个表单,其中包含 10 个数字字段、5 个字符串字段和 5 个用户必须填写的字段。
因此,我们需要控制许多**不合逻辑**的事件。

Using the Code

我们需要一些关于验证的方法,以便能够拥有一个用于控制验证的类。 例如:我们需要 3 种数据类型进行验证。 如果我们创建用于验证的组件,那么你需要编辑和自定义组件以适应你的项目,这不是一个好的方法,因此我们使用类并根据你的需要定义一些方法。

  • 未知
  • 非空
  • 数值
  • 字母
  • Range

使用Enum类型定义验证方法

Public Enum ValidationType as byte
          UnKnow = 0
          NotNull = 1
          Numeric = 2
          Alphabet = 4
          Range = 8
End Num 

现在我们需要定义一些对象来响应接收到的数据。
该对象称为Errorprovides,它是你在 .NET 2005 中的授权,通过使用它可以处理定义的数据条目。 这是实现该类的方法。

     Public Class Shell_Validator
     ' generated by Ardavan Sharifi 
     Shared Ep As ErrorProvider
     Public Enum ValidationType As Byte
          UnKnow = 0
          NotNull = 1
          Numeric = 2
          Alphabet = 4
          Range = 8
     End Enum
     Sub New()

     End Sub
     Public Overloads Shared Sub ValidTextbox_
	(ByVal vType As ValidationType, ByVal Ctl As Control)
          Ep = New ErrorProvider(Ctl.FindForm)
          If vType > 0 Then
                Ctl.CausesValidation = True
                Ctl.AccessibleDescription = CType(vType, Byte)
                If (vType And 1) <> 0 Then
                     If Ctl.Tag = vbNullString Then
                          Ctl.Tag = 0 '+1 is valid length
                     End If
                End If
                AddHandler Ctl.GotFocus, AddressOf _Ctl_GotFocus
                AddHandler Ctl.Validating, AddressOf _Ctl_Validating
                ' have Numeric value So need to control event's 
                If (vType And 2) <> 0 Then      
                     AddHandler Ctl.KeyPress, AddressOf _Ctl_KeyPress
                End If
          End If
     End Sub
     Public Overloads Shared Sub ValidTextbox_
	(ByVal Ctl As Control, ByVal minRage As Int32, ByVal MaxRange As Int32, _
              Optional ByVal vType As ValidationType = ValidationType.Range)
          If vType > 0 Then
                Ctl.CausesValidation = True
                Ctl.AccessibleDescription = CType(vType, Byte)
                If (vType And 1) <> 0 Then
                     If Ctl.Tag = vbNullString Then
                          Ctl.Tag = "0," & minRage & "," & MaxRange    ' for find range
                     Else
                          Ctl.Tag &= "," & minRage & "," & MaxRange
                     End If
                Else
                     Ctl.Tag = "-1," & minRage & "," & MaxRange
                End If
                AddHandler Ctl.Validating, AddressOf _Ctl_Validating
                AddHandler Ctl.GotFocus, AddressOf _Ctl_GotFocus 'for show error label
                ' have Numeric value So need to control event's 
	       If (vType And 2) <> 0 Then      
                     AddHandler Ctl.KeyPress, AddressOf _Ctl_KeyPress
                End If
          End If
     End Sub
     Private Shared Sub _Ctl_GotFocus_
	(ByVal sender As Object, ByVal e As System.EventArgs)
          Dim Ctl As Control
          Ctl = CType(sender, Control)
          If Len(Ep.GetError(Ctl)) > 0 Then
                'so has error
                Dim Lblvalidation As New Label
                Lblvalidation.Name = "valid_" & Ctl.Name
                Lblvalidation.Left = Ctl.Left + Ctl.Width + 18
                Lblvalidation.Top = Ctl.Top + 4
                Lblvalidation.Text = Ep.GetError(Ctl)
                Lblvalidation.Width = Lblvalidation.Text.Length * 5.8
                Lblvalidation.BackColor = Color.SkyBlue
                Lblvalidation.BorderStyle = BorderStyle.FixedSingle
                Lblvalidation.Height = 15
                Lblvalidation.ForeColor = Color.Red
                Ctl.FindForm.Controls.RemoveByKey("valid_" & Ctl.Name)
                Ctl.FindForm.Controls.Add(Lblvalidation)
          End If

     End Sub
     Private Shared Sub _Ctl_Validating(ByVal sender As Object, _
		ByVal e As System.ComponentModel.CancelEventArgs)
          Dim Vtype As ValidationType
          Vtype = Byte.Parse(CType(sender, Control).AccessibleDescription)
          Dim MyTag() As String
          MyTag = Split(CType(sender, Control).Tag, ",")
          If (Vtype And ValidationType.NotNull) <> 0 Then     ' Not null value 
                Dim ValidLength As Integer = Int32.Parse(MyTag(0)) + 1
                If CType(sender, Control).Text.Length < ValidLength Then
                     GoError(sender, "Required!")
                     e.Cancel = True
                     Exit Sub
                Else
                     ClearError(sender)
                     e.Cancel = False
                End If
          End If
          If (Vtype And ValidationType.Numeric) <> 0 Then     'Numeric Type
                If Not isChecker(CType(sender, Control).Text, 1) Then
                     GoError(sender, "Please Insert number value!")
                     e.Cancel = True
                Else
                     ClearError(sender)
                End If
          ElseIf (Vtype = ValidationType.Alphabet) Or (Vtype = _
		ValidationType.Alphabet + ValidationType.NotNull) Then    _
                                  'Alphabet or Alphabet And Not Null
                If Not isChecker(CType(sender, Control).Text, 0) Then
                     GoError(sender, "Please Insert letter!")
                     e.Cancel = True
                Else
                     ClearError(sender)
                End If
          ElseIf (Vtype = 6) Then 'Alphabet & Number
                If Not isChecker(CType(sender, Control).Text, 2) Then
                     GoError(sender, "Please Insert number or Letter value!")
                     e.Cancel = True
                Else
                     ClearError(sender)
                End If
          End If
          If (Vtype And 8) <> 0 Then
                Dim Vv As Int64 = 0
                If Int64.TryParse(CType(sender, Control).Text, Vv) = False Then
                     GoError(sender, "Please Insert Number value!")
                     e.Cancel = True
                Else
                     If (Vv <= Convert.ToInt64(MyTag(1))) Or (Vv >= _
					Convert.ToInt64(MyTag(2))) Then
                          GoError(sender, "Please Insert Number in " & _
					MyTag(1) & " And " & MyTag(2) & " !")
                          e.Cancel = True
                     Else
                          ClearError(sender)
                     End If
                End If
          End If
     End Sub

如何在验证中使用正则表达式

这里我们有一个用于检查输入数据的函数

isChecker(ByVal MyStr As String, ByVal chktype As Byte) 

在这个函数中,你可以使用带有定义模式的regex。 所以你需要一个。

readonly property(entry) as boolean

对于定义正则表达式,你可以使用这个例子:这个函数返回 0 到 127 之间的entry的验证。

 Public ReadOnly Property isinRang(ByVal entry As String) As Boolean
        Get
      Return New Regex("^(0?[0-9]?[0-9]|1[0-1][0-9]|12[0-7])$", _
		RegularExpressions.RegexOptions.IgnoreCase).IsMatch(entry)
        End Get
    End Property

此函数返回entry是数字还是字母的验证。

    Public ReadOnly Property IsAlphaNumeric(ByVal entry As String) As Boolean
        Dim c As New Regex("[^a-zA-Z0-9]").IsMatch(entry)
    End Function

更多示例

匹配 0 到 255 之间的数字: ^([01][0-9][0-9]|2[0-4][0-9]|25[0-5])$

匹配 000 到 255 之间的数字:^([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$

匹配 0 到 127 之间的数字:^(0?[0-9]?[0-9]|1[0-1][0-9]|12[0-7])$

有关正则表达式的更多信息,我建议你查看正则表达式并阅读本文正则表达式的使用。 现在你可以用isChecker函数的部分替换你的函数,我使用了 char 的函数。

如果你想在验证类上使用 regex,你可以拒绝输入。

优化的代码

Page_Load()中,只需为对象调用验证函数

     ValidTextbox(ValidationType.NotNull, TextBox1)
     ValidTextbox(ValidationType.Numeric, TextBox2)
     ValidTextbox(3, TextBox3) ' Numeric And Not Null
     ValidTextbox(ValidationType.Alphabet, TextBox4) ' Alphabet
     ValidTextbox(ValidationType.UnKnow, TextBox5)    ' Free Format
     ValidTextbox(TextBox6, 18, 60, 9)    ' Range Type
     ValidTextbox(5, TextBox7) 'Alphabet And Not Null 
     ValidTextbox(ValidationType.Alphabet, Me.ComboBox1)    ' Only Alphabet

你可以使用这种方式定义关于你应用程序的不同类型的验证。 你可以使用 **tooltip** 对象或其他对象。 当你使用 Errorprovider 和此类时,你可能还想自定义生成的代码以满足你自己的需求。

最后,你可以通过调用ValidateChildren()来检查验证表单

 If ValidateChildren() = True Then
   MsgBox("Your information approved !!!", MsgBoxStyle.Information)
 End If

注意

如果你在你的项目中使用 regex 类,请不要忘记注意以下事项

  imports System.Text.RegularExpressions 

在本文中,所有重点都放在验证事件上,因此该事件对我们很重要,我们必须实现动态。 你还可以使用属性的 tag 来控制授权字符的数量。 在Page_Load事件中调用用于验证的基础函数。 现在在验证数据处理过程中,我们使用此函数。 在实现这些方法之后,你可以确保输入数据和验证的正确性。

© . All rights reserved.