控件遍历算法的优化,还不能满足需要,正在寻求更好的解决方式
很久以前对于winform窗体的编程,我很想实现 通过字符串来找到窗体控件,并加以控制的功能。这样可以实现程序更广的灵活度,可惜在vb.net中是不支持如同 me."TextBox".Text 这种语法的。通过收集csdn相关资料和平时积累的经验,圆满的完成了此功能。但问题也随即出现了....
问题的提出:实现winfrom窗体所有录入控件的数据验证
涉及的控件类型:XtraEditor系列控件(TextEdit、LookUpEdit、DateEdit)这几个控件只是把WinForm自带的Textbox、ComboBox以及日期控件的局部功能作了一个扩展,这里我就不细说,有兴趣的朋友可以自行去研究。
算法描述:
遍历窗体中的控件,得到控件的名称(ID)
遍历数据库中字典表,查询出包含上面得到的ID字符串信息记录,得到该字段的主键、数据类型等信息
注意:数据库中字典表记录所有表格字段的信息,窗体中绑定字段控件的名称与字段名一致,方便操作
通过字段的主键和数据类型信息,进行数据验证。
程序模块的实现:
1.对外控件数据验证主模块
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.数字数据类型验证模块
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.字符串数据验证模块
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.日期数据验证模型
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
模块调用
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秒。