.NET公共函数中通过With语句使用变量窗体与DataGridView名可行吗?
问题解答:在With结构中使用变量窗体名和DataGridView名
当然可行,但你当前的写法存在关键问题——VB.NET没办法直接把字符串变量当成窗体或控件的引用解析,FORM_NAME.DGV_NAME里的两个字符串并不会被编译器识别为对应的窗体和DataGridView实例,得先通过名称找到真实的对象才行。
为什么原代码无法运行?
你的代码里FORM_NAME和DGV_NAME都是字符串类型,VB.NET会把FORM_NAME.DGV_NAME当成字符串的属性调用(而字符串根本没有DGV_NAME这个属性),自然会报错。要解决这个问题,我们需要先通过字符串名称找到对应的窗体和控件实例。
修改后的可行代码
这里提供一个健壮性更强的版本,包含必要的空值判断,避免空引用异常:
Public Function FillOrNullFieldFromDataTable(dgvField As String, formName As String, dgvName As String) As Object ' 第一步:从已打开的窗体集合中找到目标窗体 Dim targetForm As Form = Application.OpenForms.OfType(Of Form)().FirstOrDefault(Function(f) f.Name.Equals(formName, StringComparison.OrdinalIgnoreCase)) ' 如果找不到目标窗体,直接返回Nothing(也可以根据需求抛出异常) If targetForm Is Nothing Then Return Nothing End If ' 第二步:从窗体中递归查找目标DataGridView控件 ' Controls.Find的第二个参数设为True,表示查找所有子控件(包括嵌套在容器里的) Dim targetDgv As DataGridView = targetForm.Controls.Find(dgvName, True).FirstOrDefault() ' 检查DGV是否存在,以及是否有选中的当前行 If targetDgv Is Nothing OrElse targetDgv.CurrentRow Is Nothing Then Return Nothing End If ' 第三步:判断字段值并返回结果,这里可以正常使用With结构 With targetDgv.CurrentRow If IsDBNull(.Cells(dgvField).Value) OrElse .Cells(dgvField).Value Is Nothing Then FillOrNullFieldFromDataTable = Nothing Else FillOrNullFieldFromDataTable = .Cells(dgvField).Value End If End With End Function
额外注意事项
- 如果你的窗体是未打开的新窗体(还没实例化),
Application.OpenForms里会找不到它,这种情况需要用反射来实例化窗体,不过一般业务场景中都是操作已打开的窗体,所以上面的代码足够覆盖大部分情况。 - 加上空值判断很重要,能避免程序因找不到窗体、控件或无当前行而崩溃。
- 变量名改用
PascalCase(首字母大写)更符合VB.NET的命名规范,可读性会更好。
内容的提问来源于stack exchange,提问作者Julien Lavoie
相关产品推荐
相关产品推荐

