0

我有一个 MDI 主窗体。我在上面托管了一个表单,我希望它在关闭之前显示一个消息框(询问用户是否保存更改)。

到目前为止一切顺利,但是我发现关闭 MDI 主窗体不会引发 MDI 子 FormClosing 事件。我想我会在 MDI 主的 FormClosing 事件(确实会引发)中调用MdiChild .Close() 。这个接缝可以工作,但它确实会导致问题......

在我显示的消息框中,我让用户保存更改,而不是保存更改并取消关闭。通常这工作正常,但我似乎无法找到取消 MDI 主的 FormClosing 事件的方法。有没有一种优雅的方式来做到这一点?

编辑:我通过抛出异常(当用户决定取消关闭程序时)解决了这个问题,该异常在 MDI 主的 FormClosing 事件中被捕获。通过这种方式,我知道何时必须取消 MDI 主的 FormClosing 事件,并且这个接缝可以正常工作......但是我无法相信这个“​​hax”是这样做的唯一方法。肯定有更好的方法吗?

4

3 回答 3

3

我想当用户投票取消关闭时,您取消了子窗体上的关闭?

在那种情况下,我会选择关闭这个主表单

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);
}
于 2010-05-10T09:04:50.410 回答
1

我建议您不要调用子表单,而是Close可以创建一个像ReadyToClose子表单一样的方法,然后主表单循环并为每个子表单调用它,它会向用户提问并执行如果需要保存,最后如果可以继续,它将返回 true。

如果所有孩子都对关闭进行“投票”,那么您将其全部关闭,否则您什么也不关闭。

于 2010-05-10T08:54:48.093 回答
1

关闭 MDI 主窗体时,首先调用所有子关闭事件,因此,在 foreach 循环上调用 frm.Close() 时,再次调用子关闭事件(我不知道为什么它们应该已经关闭) .

ho1 的建议对我来说效果很好。这是我修改后的 foreach 循环(ClosableMDIChildForm 是一个包含 IsOkToClose() 方法的接口):

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

显然,this.MdiChildren 表单必须实现 ClosableMDIChildForm 接口。决定是否可以关闭窗口的逻辑在 IsOkToClose() 的实现中。

于 2010-08-02T23:14:51.613 回答