3

所以,我一直在 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 交换为 Load 会破坏某些东西,我有点害怕 :(。

4

1 回答 1

6

试试这个代码

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

这对我有用

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

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

ISynchronizationInvoke's成员 (InvokeBeginInvoke) 由Control类实现如下。

  1. 获取创建窗口的线程的上下文。
  2. 使用生成一个新窗口 messageIdRegisterWindowMessage
  3. 封装我们作为参数传递的委托,ThreadMethodEntry将其添加到控件的内部Queue
  4. RegisterWindowMessage使用返回的 messageId 将消息发布到线程的队列PostMessage
  5. HandlesWndProc监听messageId然后 De-queuesThreadMethodEntry并调用委托。

这里出了什么问题?

表格 1 表格 1 = 新表格 1(); form1.Show(); form1.MdiParent = 这个;

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并将其状态设置为已完成,而不调用委托但将其标记为 throw 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();before轻松解决此问题,form1.MdiParent = this;因为DoEvents会立即处理所有未决消息。

于 2013-08-19T19:35:25.243 回答