C# WinForm技术问询:点击按钮关闭当前窗口并刷新已有窗口DataGridView
解决WinForm关闭窗口时刷新另一窗口DataGridView的问题
嘿,刚接触C# WinForm的时候我也踩过类似的跨窗口刷新坑,给你分享两个亲测有效的解决方案:
方案一:事件委托实现低耦合通信(推荐)
这种方式是WinForm里比较规范的跨窗口交互做法,耦合度低,扩展性强:
- 在你要关闭的子窗口中定义自定义事件:
public partial class ChildForm : Form { // 定义触发刷新的自定义事件 public event Action OnCloseTriggerRefresh; public ChildForm() { InitializeComponent(); } private void btnClose_Click(object sender, EventArgs e) { // 先触发事件通知主窗口刷新 OnCloseTriggerRefresh?.Invoke(); // 再关闭当前子窗口 this.Close(); } }
- 在主窗口打开子窗口时,订阅这个事件:
public partial class MainForm : Form { public MainForm() { InitializeComponent(); // 初始化加载DataGridView数据 LoadDgvData(); } // 封装数据加载逻辑,方便复用 private void LoadDgvData() { // 这里写你的数据绑定逻辑,比如从数据库查询后赋值给DataGridView // 示例:dataGridView1.DataSource = 你的数据源集合; } private void btnOpenChild_Click(object sender, EventArgs e) { ChildForm childWin = new ChildForm(); // 订阅子窗口的刷新事件 childWin.OnCloseTriggerRefresh += () => { // 必须处理线程安全,避免跨线程操作UI报错 if (dataGridView1.InvokeRequired) { dataGridView1.Invoke(new Action(LoadDgvData)); } else { LoadDgvData(); } }; childWin.Show(); } }
方案二:通过Application.OpenForms直接调用主窗口方法
如果你的场景比较简单,也可以直接定位到已打开的主窗口,调用它的刷新方法:
- 在主窗口中公开一个刷新DataGridView的方法:
public partial class MainForm : Form { public MainForm() { InitializeComponent(); LoadDgvData(); } private void LoadDgvData() { // 数据加载逻辑 } // 公开刷新方法,供子窗口调用 public void RefreshDataGridView() { if (dataGridView1.InvokeRequired) { dataGridView1.Invoke(new Action(LoadDgvData)); } else { LoadDgvData(); } } }
- 子窗口关闭按钮点击时,找到主窗口并执行刷新:
private void btnClose_Click(object sender, EventArgs e) { // 遍历所有已打开的窗口,找到主窗口实例 foreach (Form form in Application.OpenForms) { if (form is MainForm mainWin) { mainWin.RefreshDataGridView(); break; } } this.Close(); }
关键注意点
- 线程安全必须处理:子窗口的关闭事件可能不在主窗口的UI线程,直接操作DataGridView会抛出异常,一定要用
InvokeRequired判断并切换到UI线程执行刷新。 - 如果主窗口可能存在多个实例,方案一的事件委托会更精准,因为它绑定的是当前打开子窗口对应的那个主窗口实例。
内容的提问来源于stack exchange,提问作者Valkr1n
相关产品推荐
相关产品推荐

