设置表单的MdiParent属性会中断/阻止其已显示的事件被触发

时间:2013-08-19 19:29:22

标签: c# winforms events mdi

所以,我一直在通过stackoverflow和其他互联网论坛和知识库搜索类似的主题,但到目前为止,我没有运气试图解决这个问题,我一直在努力整整一周。这是代码:

    private void matrículasToolStripMenuItem_Click(object sender, EventArgs e)
    {
        Form1 form1 = new Form1();
        form1.Show();
        form1.MdiParent = this; // this == the main form of the aplication, wich has IsMdiParent property set to true.
    }

如果我取出“form1.MdiParent = this”,form1的显示事件将正常触发,执行其所有处理程序的内容,但如果我让它在那里,form1的显示事件将不会触发(我确实设置了)破坏,没有一个触发)。

奇怪的是,如果我使用Load事件而不是Shown,一切正常,但是如果交换Shown for Load会破坏某些东西我会有点害怕:(。

1 个答案:

答案 0 :(得分:5)

试试此代码

 Form1 form1 = new Form1();
 //Subscribe event here
 form1.MdiParent = this;
 form1.Show();

这对我有用

我不知道为什么你的代码不起作用,一旦得到答案我就会回来。

编辑:我现在得到了答案。

ISynchronizationInvoke's成员(InvokeBeginInvoke)由Control类实施,如下所示。

  1. 获取创建窗口的Thread的上下文。
  2. 使用RegisterWindowMessage
  3. 生成新窗口messageId
  4. 将我们作为参数传递的委托封装在ThreadMethodEntry中,将其添加到控件的内部Queue
  5. 使用RegisterWindowMessage
  6. 将消息发布到PostMessage返回的messageId的线程队列中
  7. 句柄WndProc侦听messageId,然后对ThreadMethodEntry进行排队并调用委托。
  8.   

    这里出了什么问题?

    Form1 form1 = new Form1();    form1.Show();    form1.MdiParent = this;

    Form.Show以某种方式导致调用OnLoad方法,即使用OnShown异步调用BeginInvoke

    if (base.IsHandleCreated)
    {
        base.BeginInvoke(new MethodInvoker(this.CallShownEvent));//reflected code
    }
    

    因此,在发布的WindowMessage收到之前,您设置了form1.MdiParent = this;,而Destroy又将控件强制为ReCreate它的句柄和DestroyHandle新句柄。

    PeekMessage方法通过使用Queue函数获取已发布的消息,然后枚举ObjectDisposedException中的所有元素,并将其状态设置为已完成,而不调用委托但将其标记为要抛出Form1 form1 = new Form1(); form1.Show(); Action del = () => { Console.WriteLine("This will never be called");//our custom delegates too fails to be invoked }; var res = form1.BeginInvoke(del); //after some more code form1.EndInvoke(res);//throws `ObjectDisposedException` which was marked previously form1.MdiParent = this;

    ObjectDisposedException("Control")

    投掷Application.DoEvents();实际上是误导性的不是吗?

    注意:您可以在form1.MdiParent = this;之前使用DoEvents轻松解决此问题,因为{{1}}会立即处理所有待处理的消息。