非模态窗口下如何从FormVendorDetail更新FormVendor控件
非模态窗体间控件更新解决方案
问题场景
通过代码创建父窗体FormVendor(Dim FormVendor As New FormTempSint),该窗体包含计数器Label和绑定数据库数据的DataGridView;双击DataGridView行时,以非模态方式打开详情窗体FormVendorDetail(Dim FormVendorDetail As New FormTempDetail)。需在详情窗体保存数据后,更新父窗体的DataGridView和计数器Label,且不能使用ShowDialog模态窗口方式。
方法1:自定义事件实现(推荐,低耦合)
通过子窗体触发自定义事件,父窗体订阅事件完成更新,避免窗体间直接依赖。
步骤1:在子窗体FormTempDetail中定义事件
Public Class FormTempDetail ' 定义更新完成事件,如需传递数据可自定义EventArgs子类 Public Event DataUpdated As EventHandler Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click ' 执行数据库保存逻辑... ' 保存完成后触发更新事件 RaiseEvent DataUpdated(Me, EventArgs.Empty) ' 可选:关闭子窗体 Me.Close() End Sub End Class
步骤2:在父窗体FormTempSint中订阅事件
创建子窗体时绑定事件,在事件处理方法中更新控件:
Public Class FormTempSint Private Sub dgvVendor_CellDoubleClick(sender As Object, e As DataGridViewCellEventArgs) Handles dgvVendor.CellDoubleClick Dim formDetail As New FormTempDetail() ' 订阅子窗体的更新事件 AddHandler formDetail.DataUpdated, AddressOf RefreshVendorData formDetail.Show() End Sub ' 控件更新逻辑 Private Sub RefreshVendorData(sender As Object, e As EventArgs) ' 重新加载DataGridView数据 LoadVendorData() ' 更新计数器Label lblCounter.Text = $"共 {dgvVendor.Rows.Count} 条数据" End Sub ' 封装数据库查询逻辑(原有代码提取为公共/私有方法) Private Sub LoadVendorData() ' 执行数据库查询并绑定到DataGridView ' 示例: ' Dim dt As DataTable = GetVendorListFromDB() ' dgvVendor.DataSource = dt End Sub End Class
方法2:传递父窗体引用(简单但耦合度高)
直接将父窗体实例传递给子窗体,子窗体通过引用调用父窗体的更新逻辑。
步骤1:修改子窗体构造函数
Public Class FormTempDetail Private _parentForm As FormTempSint ' 重载构造函数,接收父窗体实例 Public Sub New(parentForm As FormTempSint) InitializeComponent() _parentForm = parentForm End Sub Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click ' 执行保存逻辑... ' 调用父窗体的更新方法 _parentForm.LoadVendorData() _parentForm.lblCounter.Text = $"共 {_parentForm.dgvVendor.Rows.Count} 条数据" Me.Close() End Sub End Class
步骤2:创建子窗体时传入父窗体引用
Public Class FormTempSint Private Sub dgvVendor_CellDoubleClick(sender As Object, e As DataGridViewCellEventArgs) Handles dgvVendor.CellDoubleClick ' 传入当前父窗体实例 Dim formDetail As New FormTempDetail(Me) formDetail.Show() End Sub ' 需将该方法设为Public,供子窗体调用 Public Sub LoadVendorData() ' 数据库查询与DataGridView绑定逻辑 End Sub End Class
注意事项
- 优先使用事件机制,降低窗体间耦合度,便于后续维护
- 非模态窗体需注意资源释放,避免内存泄漏
- 若需传递更新后的具体数据,可自定义
EventArgs子类,在事件中传递实体对象或ID,实现精准更新而非全量重载
内容的提问来源于stack exchange,提问作者Roberto Rossi
相关产品推荐
相关产品推荐

