C# 设置窗体的MdiParent属性会中断/防止触发其显示的事件

C# 设置窗体的MdiParent属性会中断/防止触发其显示的事件,c#,winforms,events,mdi,C#,Winforms,Events,Mdi,所以,我一直在stackoverflow和其他互联网论坛和知识库上搜索类似的主题,但到目前为止,我还没有找到解决这个问题的方法,我已经苦苦挣扎了整整一周。代码如下: private void matrículasToolStripMenuItem_Click(object sender, EventArgs e) { Form1 form1 = new Form1(); form1.Show(); form1.MdiParent =

所以,我一直在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事件而不是Showed,一切都正常,但我有点担心如果将Showed替换为Load会破坏某些东西:(。

试试这段代码

 Form1 form1 = new Form1();
 //Subscribe event here
 form1.MdiParent = this;
 form1.Show();
这对我有用

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

编辑:我现在得到答案了

ISynchronizationInvoke的
成员(
Invoke
BeginInvoke
)由
控件
类实现,如下所示

  • 获取创建窗口的线程的上下文
  • 使用
    RegisterWindowMessage
  • 将我们作为参数传递的委托封装在
    ThreadMethodEntry
    中,并将其添加到控件的内部
    队列中
  • 使用
    PostMessage
    RegisterWindowMessage返回的messageId将消息发布到线程队列
  • 处理
    WndProc
    侦听
    messageId
    ,然后对
    ThreadMethodEntry
    解除队列并调用委托
  • 这里出了什么问题

    Form1 Form1=新Form1(); 表1.Show(); form1.MdiParent=此

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

    if (base.IsHandleCreated)
    {
        base.BeginInvoke(new MethodInvoker(this.CallShownEvent));//reflected code
    }
    
    因此,在发布的
    窗口消息
    接收之前,您可以设置
    form1.MdiParent=this;
    ,这反过来会强制控件销毁它的句柄并重新创建新句柄

    DestroyHandle
    方法通过使用
    PeekMessage
    函数获取已发布的消息来吞咽该消息,然后枚举
    队列中的所有元素
    ,并将其状态设置为完成,而不调用委托,但将其标记为抛出
    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(“控件”)
    实际上是误导,不是吗


    注意:您可以使用
    Application.DoEvents()轻松修复此问题
    之前
    form1.MdiParent=this;
    因为
    DoEvents
    会立即处理所有待处理的邮件。

    天哪,太感谢了!真不敢相信我已经为这件事苦苦挣扎了一周,解决办法很简单:哦,伙计,一周时间太长了。不过很高兴你现在收到了。我会让你知道为什么它不起作用ce我找到了。我很好奇为什么它不起作用。我找到了,更新了我的答案