C#MDI父项何时检测MDI子项关闭?

C#MDI父项何时检测MDI子项关闭?,c#,mdi,mdichild,mdiparent,formclosing,C#,Mdi,Mdichild,Mdiparent,Formclosing,我试图在MDI父窗体上检测我的MDI子窗体何时关闭,并做出相应的反应。MDI父级在MDI子级关闭之前不应执行任何操作。这是我的代码,我不确定我做错了什么,但是我添加的表单关闭事件方法从未被调用 以下代码位于MDI父类中(如果不明显) private void keyValidation() { if (Properties.Settings.Default.Unlock == true) return; else

我试图在MDI父窗体上检测我的MDI子窗体何时关闭,并做出相应的反应。MDI父级在MDI子级关闭之前不应执行任何操作。这是我的代码,我不确定我做错了什么,但是我添加的表单关闭事件方法从未被调用

以下代码位于MDI父类中(如果不明显)

    private void keyValidation()
    {
        if (Properties.Settings.Default.Unlock == true)
            return;
        else
        {
            menu.Enabled = false;
            statusStrip.Enabled = false;

            ValidationForm vf = new ValidationForm();
            vf.MdiParent = this;
            vf.Show();
            vf.FormClosed += new FormClosedEventHandler(validationForm_FormClosed);
        }
    }

    void validationForm_FormClosed(object sender, FormClosedEventArgs e)
    {
        MessageBox.Show("Got here");
        if (Properties.Settings.Default.Unlock == true)
        {
            menu.Enabled = true;
            statusStrip.Enabled = true;
        }
    }

谢谢你的帮助

也许,只是也许,你有一个隐藏而不是关闭的子窗体。尝试挂接VisibleChanged,看看会发生什么


此外,Falm关闭将允许您取消关闭,FeloCutt不给您选项。

虽然这并不能真正解决您所指的问题,但从用例的角度来看,您可能需要考虑打开验证表单作为模态对话框而不是MDI子。


您可以使用表单的方法执行此操作,其中现在有
Show()
。请记住,
ShowDialog()
如果将它们分配给其他窗体上的按钮,也可以返回一个值。

不要使用
关闭事件。相反,请使用
FormClosing
事件:

private void frmMain_FormClosing(object sender, FormClosingEventArgs e){
  if (MessageBox.Show("Are you sure you want to Exit", "Confirmation", MessageBoxButtons.YesNo,MessageBoxIcon.Information) == System.Windows.Forms.DialogResult.No) {
    e.Cancel = true;
  }
}

通过将IsMdiContainer设置为true将父窗体标记为MdiContainer时,将引发ParentForm.ControlAdded事件,以将“MdiClient”控件添加到父窗体。因此,当将MdiClient添加到父MDI表单时,我们可以为MdiClient控件引发ControlAdded事件,如下所示

  public ParentForm()
  {
    InitializeComponent();
    this.ControlAdded += Form1_ControlAdded;
    this.IsMdiContainer = true;
我们需要提高MdiClient.ControlAdd,如下所示

    void Form1_ControlAdded(object sender, ControlEventArgs e)
      {
           if(e.Control is MdiClient)
                e.Control.ControlAdded += MdiClient_ControlAdded;

      }
默认情况下,MDI子表单添加到父表单中MdiClient的控件集合中。因此,当将ChildForm.MdiParent值设置为父窗体时,MdiClient的ControlAdded事件将引发

void MdiClient_ControlAdded(object sender, ControlEventArgs e)
{
    if (e.Control is Form)
        {
            var form = e.Control as Form;
            form.FormClosing += form_FormClosing;
            form.FormClosed += form_FormClosed;
        }
}

在上面的MdiClient_ControlAdded中,当子窗体添加到父MDI窗体时,将引发方法。因此,通过引发子窗体的FormClosing和FormClosed事件,您可以轻松检测子窗体是否已关闭。

当您只需将MDI父窗体的事件处理程序调用到MDI子窗体时,为什么要执行这么多操作

假设我想在孩子被激活或停用时做某些事情。您只需要声明MDI父级的一些事件处理程序(例如,
SetupToolStripMenu\u PlantMasterRecipe
),并在其中提及一些您想要执行的逻辑。通过这种方式,您可以从MDI父对象控制MDI子对象的每个对象行为

这里objB是我的子表单,我在MDI父表单中编写以下代码:

objB.MdiParent = this;

objB.Activated += SetupToolStripMenu_PlantMasterRecipe;

objB.Deactivate += DisposeToolStripMenu;

objB.Show();

关于创建公共函数

public void MakeMenuVisible()
{
MainMenu.visible = true;
}
然后在childform上可以像这样运行函数

private void ChildForm_FormClosed(object sender, FormClosedEventArgs e)
{
//Cast MdiParent to Mainform
((mainform)this.MdiParent).MakeMenuVisible();  
}

另外,有人能解释一下使用表单关闭和表单关闭在执行上的区别吗?我应该使用哪一个呢?
表单关闭
事件在
关闭
之前调用。例如,您可以使用
关闭事件查看用户是否需要保存文档。感谢您的澄清,我想这是为了保存表单拥有的任何内容而做的最后努力。
FormClosing
还允许您通过将
FormClosingEventArgs
设置为
true
来取消关闭。我们不是在看真正的代码。如前所述,它应该是有效的。但是是的,这几乎肯定需要是一个对话框,而不是MDI子对象。