控件遍历算法的优化,还不能满足需要,正在寻求更好的解决方式
很久以前对于winform窗体的编程,我很想实现 通过字符串来找到窗体控件,并加以控制的功能。这样可以实现程序更广的灵活度,可惜在vb.net中是不支持如同 me."TextBox".Text 这种语法的。通过收集csdn相关资料和平时积累的经验,圆满的完成了此功能。但问题也随即出现了....
问题的提出:实现winfrom窗体所有录入控件的数据验证
涉及的控件类型:XtraEditor系列控件(TextEdit、LookUpEdit、DateEdit)这几个控件只是把WinForm自带的Textbox、ComboBox以及日期控件的局部功能作了一个扩展,这里我就不细说,有兴趣的朋友可以自行去研究。
算法描述:
遍历窗体中的控件,得到控件的名称(ID)
遍历数据库中字典表,查询出包含上面得到的ID字符串信息记录,得到该字段的主键、数据类型等信息
注意:数据库中字典表记录所有表格字段的信息,窗体中绑定字段控件的名称与字段名一致,方便操作
通过字段的主键和数据类型信息,进行数据验证。
程序模块的实现:
1.对外控件数据验证主模块
Public Function CheckAllInputData(ByVal tbinfo, ByVal FormName) As Boolean
Dim i As Integer
Dim tempcontrol As Control
For Each tempcontrol In FormName.Controls
For i = 0 To tbinfo.Rows.Count - 1
If tempcontrol.Name = tbinfo.Rows(i)(2) Then
If tbinfo.Rows(i)(3) = tbinfo.Rows(i)(4) And tbinfo.Rows(i)(8) = "No" And tbinfo.Rows(i)(5) <> "DATE" Then
Dim BeCheckStr As String = tempcontrol.Text
Dim DataTypeName, DataTypeStr As String
DataTypeName = tbinfo.Rows(i)(5)
DataTypeStr = DataTypeName
DataTypeName = DataTypeName.Substring(0, 4)
Select Case DataTypeName
Case "VARC"
Dim strlen As Integer = DataTypeStr.Substring(8, DataTypeStr.LastIndexOf(")") - 8)
If Trim(BeCheckStr) = "" And tbinfo.Rows(i)(6) = "No" Then
Else
If CheckStrLen(BeCheckStr, strlen, tbinfo.Rows(i)(3)) = True Then
' InsertTempvalue(BeCheckStr, tbinfo.Rows(i)(2))
Else
ClearTempvalue()
tempcontrol.Focus()
Return False
End If
End If
Exit Select
Case "NUMB"
If Trim(BeCheckStr) = "" And tbinfo.Rows(i)(6) = "No" Then
Else
Dim zsnum As Integer = DataTypeStr.Substring(7, DataTypeStr.LastIndexOf(",") - 7)
Dim xsnum As Integer = DataTypeStr.Substring(DataTypeStr.LastIndexOf(",") + 1, DataTypeStr.LastIndexOf(")") - DataTypeStr.LastIndexOf(",") - 1)
If CheckDec(BeCheckStr, zsnum, xsnum, tbinfo.Rows(i)(3)) = True Then
' InsertTempvalue(BeCheckStr, tbinfo.Rows(i)(2))
Else
ClearTempvalue()
tempcontrol.Focus()
Return False
End If
End If
Exit Select
Case "DATE"
BeCheckStr = CType(tempcontrol, DevExpress.XtraEditors.DateEdit).Text
If Trim(BeCheckStr) = "" And tbinfo.Rows(i)(6) = "No" Then
Else
CheckRQ(BeCheckStr, tbinfo.Rows(i)(2))
Exit Select
End If
Exit Select
Case Else
If tbinfo.Rows(i)(8) = "YES" And tbinfo.Rows(i)(6) = "YES" Then
BeCheckStr = CType(tempcontrol, DevExpress.XtraEditors.LookUpEdit).EditValue()
If Trim(BeCheckStr) = "" Then
MsgBox(tbinfo.Rows(i)(2) & "作为主键,不能为空!", MsgBoxStyle.Critical, "错误")
End If
End If
Exit Select
End Select
End If
Exit For
End If
Next
Next
Return True
End Function

2.数字数据类型验证模块
Private Function CheckDec(ByVal str As String, ByVal zsnum As Integer, ByVal xsnum As Integer, ByVal CheckField As String) As Boolean
Dim rfvxsstr As String = "^[0-9]{1," & zsnum & "}\.?[0-9]{0," & xsnum & "}$"
Dim rfvzsstr As String = "^[0-9]{1," & zsnum & "}$"
If Regex.IsMatch(str, rfvxsstr) = True Or Regex.IsMatch(str, rfvzsstr) = True Then
Return True
Else
MsgBox(CheckField & "的输入产生错误的数据格式,限制整数" & zsnum & "位,小数" & xsnum & "位", MsgBoxStyle.Critical, "错误")
Return False
End If
End Function
3.字符串数据验证模块
Private Function CheckStrLen(ByVal str As String, ByVal length As Integer, ByVal CheckField As String) As Boolean
If System.Text.UnicodeEncoding.Default.GetByteCount(str) <= length Then
Return True
Else
MsgBox(CheckField & "的输入字符过长,限制输入中文字符" & length / 2 & "个或英文字符" & length & "个。", MsgBoxStyle.Critical, "错误")
Return False
End If
End Function
4.日期数据验证模型
Public Function CheckRQ(ByVal str As String, ByVal CheckField As String) As Boolean
Dim rfvrqstr As String = "^^((\d{2}(([02468][048])|([13579][26]))[\-\/\s]?((((0?[13578])|(1[02]))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\-\/\s]?((0?[1-9])|([1-2][0-9])))))|(\d{2}(([02468][1235679])|([13579][01345789]))[\-\/\s]?((((0?[13578])|(1[02]))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\-\/\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\s(((0?[1-9])|(1[0-2]))\:([0-5][0-9])((\s)|(\:([0-5][0-9])\s))([AM|PM|am|pm]{2,2})))?$"
If Regex.IsMatch(str, rfvrqstr) = True Then
Return True
Else
MsgBox(CheckField & "的输入产生错误的时间数据格式", MsgBoxStyle.Critical, "错误")
Return False
End If
End Function 模块调用
#Region "Form中文本框数据验证 "
Private Function InpBoxDataCheck() As Boolean
Try
If TComFun.CheckAllInputData(tbinfo, Me) = True Then
Return True
Else
Return False
End If
Catch ex As Exception
Return False
End Try
End Function
#End Region

注意 标注红色的Me,如果遍历的控件的父容器不是Form而是Form下的GroupBox1,那么对应的Me应该改为Me.GroupBox1
问题的出现
程序执行中数据验证时间过长,测试窗体含有验证控件21个,验证时间20秒,代码中包含Exit字样的是优化后的代码,主要原理为一旦某项数据验证完毕,立即退出当前子循环,进行下一个父循环,优化后时间为13秒。

浙公网安备 33010602011771号