You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# WinForm技术问询:点击按钮关闭当前窗口并刷新已有窗口DataGridView

解决WinForm关闭窗口时刷新另一窗口DataGridView的问题

嘿,刚接触C# WinForm的时候我也踩过类似的跨窗口刷新坑,给你分享两个亲测有效的解决方案:

方案一:事件委托实现低耦合通信(推荐)

这种方式是WinForm里比较规范的跨窗口交互做法,耦合度低,扩展性强:

  1. 在你要关闭的子窗口中定义自定义事件:
public partial class ChildForm : Form
{
    // 定义触发刷新的自定义事件
    public event Action OnCloseTriggerRefresh;

    public ChildForm()
    {
        InitializeComponent();
    }

    private void btnClose_Click(object sender, EventArgs e)
    {
        // 先触发事件通知主窗口刷新
        OnCloseTriggerRefresh?.Invoke();
        // 再关闭当前子窗口
        this.Close();
    }
}
  1. 在主窗口打开子窗口时,订阅这个事件:
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直接调用主窗口方法

如果你的场景比较简单,也可以直接定位到已打开的主窗口,调用它的刷新方法:

  1. 在主窗口中公开一个刷新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();
        }
    }
}
  1. 子窗口关闭按钮点击时,找到主窗口并执行刷新:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 10:03:29