多窗体DataGridView操作问题:跨窗体传值与控件获取报错
问题解决:跨窗体获取同名DataGridView的值
你的代码报错原因很直接:formowner是字符串类型(存储的是窗体名称),字符串对象自然没有DataGridView1这个成员,所以不能用它来直接访问控件。下面是几种可行的解决方法:
方法1:直接使用Owner窗体实例
如果当前窗体的Owner属性已经指向了目标窗体(Form1/Form2/Form3),直接用这个实例即可,不需要转成名称字符串:
' 先判断Owner是否为目标窗体类型,同时检查控件和选中行的有效性 If TypeOf Owner Is Form1 Or TypeOf Owner Is Form2 Or TypeOf Owner Is Form3 Then Dim targetForm = Owner If targetForm.DataGridView1 IsNot Nothing AndAlso targetForm.DataGridView1.CurrentRow IsNot Nothing Then ' 转换为Integer类型,加入空值判断避免异常 Dim id As Integer = If(IsNumeric(targetForm.DataGridView1.CurrentRow.Cells(0).Value), CInt(targetForm.DataGridView1.CurrentRow.Cells(0).Value), 0) End If End If
方法2:通过控件名称直接获取(适用于不确定窗体类型的场景)
如果无法确定Owner的具体类型,但知道控件名称是DataGridView1,可以通过窗体的控件集合直接获取:
Dim ownerForm = Owner ' 从控件集合中获取DataGridView,用TryCast避免类型转换失败 Dim dgv = TryCast(ownerForm.Controls("DataGridView1"), DataGridView) ' 检查控件是否存在且有选中行 If dgv IsNot Nothing AndAlso dgv.CurrentRow IsNot Nothing Then Dim id As Integer = If(IsNumeric(dgv.CurrentRow.Cells(0).Value), CInt(dgv.CurrentRow.Cells(0).Value), 0) End If
方法3:定义接口(最规范、类型安全的方式)
为了避免类型判断的繁琐和潜在错误,建议定义统一接口,让所有包含DataGridView1的窗体实现该接口:
第一步:定义接口
Public Interface IDataGridViewHost ReadOnly Property MainDataGridView As DataGridView End Interface
第二步:让窗体实现接口
以Form1为例,Form2、Form3做同样的实现:
Public Class Form1 Implements IDataGridViewHost Public ReadOnly Property MainDataGridView As DataGridView Implements IDataGridViewHost.MainDataGridView Get Return DataGridView1 End Get End Property End Class
第三步:在目标窗体中使用接口获取控件
If TypeOf Owner Is IDataGridViewHost Then Dim hostForm = DirectCast(Owner, IDataGridViewHost) Dim dgv = hostForm.MainDataGridView If dgv.CurrentRow IsNot Nothing Then Dim id As Integer = If(IsNumeric(dgv.CurrentRow.Cells(0).Value), CInt(dgv.CurrentRow.Cells(0).Value), 0) End If End If
关键注意点
- 必须检查
CurrentRow是否为Nothing,否则会触发空引用异常 - 转换值时加入
IsNumeric判断,避免非数值类型转换失败 - 接口方式是最优解,既保证类型安全,又提升代码的可维护性
内容的提问来源于stack exchange,提问作者GuidoM.
相关产品推荐
相关产品推荐

