0

我遇到了一个奇怪的问题,当我将 MDIChild 与其父级分离时,CurrencyManager PositionChanged 事件停止工作。我在我的主应用程序中得到了这种行为,并且能够在一个简单的测试应用程序中重现它。

它是 .NET 4.8 上的 WinForms 应用程序。

测试应用程序将 Form1 作为 MDIParent,将 Form2 作为 MDIChild。启动应用程序时,Form1 被加载并立即初始化 Form2 并将其 MDIParent-Property 分配给 Form1。Form1 也有一个按钮来分离当前活动的 MDIChild,因此它可以独立移动。

public partial class Form1 : Form
{
    private void Form1_Load(object sender, EventArgs e)
    {
        Form2 frm = new Form2();
        frm.MdiParent = this;
        frm.Show();
    }

    private void btnDetachMDIChild_Click(object sender, EventArgs e)
    {
        if (ActiveMdiChild != null)
        {
            ActiveMdiChild.MdiParent = null;
        }
    }
}

Form2 有一个绑定了 CurrencyManager 的 DataTable。对于此示例,数据表被分配给 datagridview。当我单击 datagridview 中的一行时,会引发 cm_PositionChanged() 事件,并且该表单上的标签显示 CurrencyManager 的当前位置:

public partial class Form2 : Form
{

    DataTable dt;
    CurrencyManager cm;

    private void Form2_Load(object sender, EventArgs e)
    {
        prepareTable();
        fillTable();

        cm.PositionChanged += new EventHandler(cm_PositionChanged);
    }

    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));
        cm = (CurrencyManager)this.BindingContext[dt];

        dgv.DataSource = dt;
    }

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

但是,当我单击 Form1 上的“分离 MDI 子项”按钮时,Form2 被分离,但 CurrencyManager 不再起作用。显然,该事件甚至不再被提出。

我不知道为什么会发生这种情况。一个疯狂的猜测是,这是因为 Form.Handle 发生了变化,但这只是一种直觉,我不知道如何防止这种情况发生。有任何想法吗?

问题演示

4

1 回答 1

0

我找到了适合我的解决方案/解决方法:

订阅 Form2.HandleCreated-Event,将新的 BindingContext 分配给 CurrencyManager,然后重新订阅 PositionChanged-Event。还存储当前位置以方便用户:

    private void Form2_Load(object sender, EventArgs e)
    {
        prepareTable();
        fillTable();

        cm.PositionChanged += new EventHandler(cm_PositionChanged);
        this.HandleCreated += new EventHandler(Form2_HandleCreated);
    }

    private void Form2_HandleCreated(object sender, EventArgs e)
    {
        if (dt != null)
        {
            int pos = -1;
            if (cm != null) { pos = cm.Position; }
            cm = (CurrencyManager)this.BindingContext[dt];
            cm.Position = pos;
            cm.PositionChanged -= cm_PositionChanged;
            cm.PositionChanged += new EventHandler(cm_PositionChanged);
        }
    }
于 2021-11-18T08:11:57.257 回答