简体   繁体   English

如何防止MDI主窗体从MDI子窗体关闭

[英]How to prevent MDI main form closing from MDI Child

I have a MDI main form. 我有一个MDI主要表格。 On it I host a form, and I want it to show a message box before it closes (asking the user whether to save changes). 我在上面托管一个表单,希望它在关闭前显示一个消息框(询问用户是否保存更改)。

So far so good, however I have discovered that closing the MDI main form does not raise a MDI child FormClosing event. 到目前为止,到目前为止还不错,但是我发现关闭MDI主窗体不会引发MDI子FormClosing事件。 I figured I will just call MdiChild .Close() in the MDI main's FormClosing event (which does get raised). 我想我只会在MDI主程序的FormClosing事件(确实会引发)中调用MdiChild .Close()。 This seams to work, however it does causes a problem... 这可以正常工作,但是确实会导致问题...

In the messagebox that I show, I offer the user to save changes, not to save changes and cancel closing. 在显示的消息框中,我为用户提供了保存更改,而不是保存更改并取消关闭的功能。 Normally this works fine, however I can't seem to find a way to cancel MDI main's FormClosing event. 通常,这可以正常工作,但是我似乎找不到消除MDI main的FormClosing事件的方法。 Is there a elegant way of doing this? 是否有一种优雅的方法?

EDIT : I solved this by throwing an exception (when user decides to cancel the closing procedure) which is caught in MDI main's FormClosing event. 编辑 :我通过抛出一个异常(当用户决定取消关闭过程时)解决了此问题,该异常在MDI main的FormClosing事件中捕获。 In this way I know when I have to cancel the MDI main's FormClosing event and this seams to work fine ... However I just can't believe that this "hax" is the only way of doing this. 这样,我知道何时必须取消MDI主站的FormClosing事件并且此接缝才能正常工作……但是,我简直不敢相信此“ hax”是执行此操作的唯一方法。 Surely there is a better way? 当然有更好的方法吗?

I figure that you cancel the close on the childform when the user votes to cancel the close? 我认为您在用户投票取消关闭子窗体时取消了子窗体上的关闭?

In that case I'd go with this Main form close 在这种情况下,我将关闭此主窗体

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    if (e.CloseReason == CloseReason.UserClosing)
    {
        foreach (Form frm in this.MdiChildren)
        {
            frm.Close();
        }
    }
    e.Cancel = (this.MdiChildren.Length > 0);
}

I'd suggest that instead of calling Close on the childforms you could create a method like ReadyToClose in the child forms and then the main form loops through and calls that for each of the child forms and it'll ask the question to the user and do the saving if needed and finally it'll return true if ok to continue. 我建议不要在子窗体上调用Close ,而可以在子窗体中创建类似ReadyToClose的方法,然后主窗体循环遍历并为每个子窗体调用该方法,并向用户和进行保存(如果需要),最后,如果可以继续,它将返回true。

And if all of the child forms "vote" for a close, then you close it all down, otherwise you close nothing. 并且如果所有子级都进行“投票”关闭,则将其全部关闭,否则不进行任何关闭。

When closing the MDI main form, all child Close events are called first so, when calling frm.Close() on the foreach loop, Close events for the child are called again (I don't know why if they should be already closed). 关闭MDI主窗体时,将首先调用所有子级Close事件,因此,在foreach循环上调用frm.Close()时,将再次调用该子级的Close事件(我不知道为什么应该已经关闭它们) 。

ho1 suggestion worked pretty well for me. ho1的建议对我来说效果很好。 Here is my modified foreach loop (ClosableMDIChildForm is an interface which contains the IsOkToClose() method): 这是我修改的foreach循环(ClosableMDIChildForm是包含IsOkToClose()方法的接口):

foreach (ClosableMDIChildForm cmdif in this.MdiChildren)
{
    if (!cmdif.IsOkToClose())
    {
        e.Cancel = true;
        ((Form)mdifc).Focus();
        break;
    }
}

Obviously, this.MdiChildren forms must implement ClosableMDIChildForm interface. 显然,this.MdiChildren表单必须实现ClosableMDIChildForm接口。 The logic to decide if it's OK to close the window goes in the implementation of IsOkToClose(). IsOkToClose()的实现决定了是否可以关闭窗口的逻辑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM