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

.NET 4.8 WinForms MDI子窗体脱离父级后CurrencyManager的PositionChanged事件失效

问题根本原因

当MDI子窗体的MdiParent属性被设置为null时,WinForms底层会销毁子窗体原有的句柄,重新创建一个顶层窗口的新句柄。此时窗体的默认BindingContext实例会被销毁重建,你在窗体加载时缓存的CurrencyManager已经是被废弃的旧实例,其绑定的事件自然不会再触发。

可行的解决方法

方案1:监听窗体HandleCreated事件重新绑定

每次窗体句柄重建时,重新获取CurrencyManager并绑定事件,同时记得解绑旧实例的事件避免内存泄漏。修改后的Form2代码如下:

public partial class Form2 : Form
{
    DataTable dt;
    CurrencyManager cm;

    private void Form2_Load(object sender, EventArgs e)
    {
        prepareTable();
        fillTable();
        // 注册句柄创建事件
        this.HandleCreated += Form2_HandleCreated;
        BindCmEvent();
    }

    private void Form2_HandleCreated(object sender, EventArgs e)
    {
        // 句柄重建后重新绑定CurrencyManager事件
        BindCmEvent();
    }

    private void BindCmEvent()
    {
        // 先解绑旧实例的事件
        if (cm != null)
        {
            cm.PositionChanged -= cm_PositionChanged;
        }
        // 重新从当前BindingContext获取最新的CurrencyManager
        cm = (CurrencyManager)this.BindingContext[dt];
        cm.PositionChanged += cm_PositionChanged;
        // 同步当前位置显示
        lblPos.Text = cm.Position.ToString();
    }

    private void cm_PositionChanged(object sender, EventArgs e)
    {
        lblPos.Text = cm.Position.ToString();
    }

    private void prepareTable()
    {
        dt = new DataTable();
        dt.Columns.Add("Index", typeof(int));
        dgv.DataSource = dt;
    }

    private void fillTable()
    {
        for (int i = 0; i < 100; i++)
        {
            dt.Rows.Add(i);
        }
    }
}

方案2:使用独立的BindingContext

直接为窗体创建专属的BindingContext实例,不使用系统默认的实例,就不会受窗体句柄重建影响。改动量极小,推荐优先使用该方案:

// 仅需修改prepareTable方法即可
private void prepareTable()
{
    dt = new DataTable();
    dt.Columns.Add("Index", typeof(int));
    // 单独创建BindingContext,不和窗体默认实例绑定,不会随句柄重建重置
    this.BindingContext = new BindingContext();
    cm = (CurrencyManager)this.BindingContext[dt];
    cm.PositionChanged += new EventHandler(cm_PositionChanged);
    dgv.DataSource = dt;
}

内容的提问来源于stack exchange,提问作者Wombat

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 11:54:04