我有一个MDI主表单。在它上面我托管了一个表单,我希望它在关闭之前显示一个消息框(询问用户是否保存更改)。
到目前为止一直很好,但我发现关闭MDI主窗体不会引发MDI子FormClosing事件。我想我将在MDI main的FormClosing事件中调用 MdiChild .Close()(它确实被引发)。这种缝合起作用,但确实会引起问题......
在我显示的消息框中,我向用户提供保存更改,而不是保存更改并取消关闭。通常这工作正常,但我似乎无法找到取消MDI main的FormClosing事件的方法。这样做有一种优雅的方式吗?
编辑:我通过抛出MDI main的FormClosing事件中捕获的异常(当用户决定取消关闭过程时)解决了这个问题。通过这种方式我知道什么时候我必须取消MDI main的FormClosing事件并且这个接缝工作正常...但是我只是不相信这个“hax”是这样做的唯一方法。当然有更好的方法吗?
答案 0 :(得分: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);
}
答案 1 :(得分:1)
我建议您不要在子表单上调用Close
,而是可以在子表单中创建类似ReadyToClose
的方法,然后主表单循环并为每个子表单调用并且它会向用户提出问题并在需要时进行保存,如果可以继续,它将返回true。
如果所有的孩子都表示“投票”结束,那么你将其全部关闭,否则你什么都不关闭。
答案 2 :(得分:1)
当关闭MDI主窗体时,首先调用所有子Close事件,因此,当在foreach循环上调用frm.Close()时,将再次调用子事件的Close事件(我不知道为什么它们应该是已经关闭了。)
对我来说,这个建议很有用。这是我修改过的foreach循环(ClosableMDIChildForm是一个包含IsOkToClose()方法的接口):foreach (ClosableMDIChildForm cmdif in this.MdiChildren)
{
if (!cmdif.IsOkToClose())
{
e.Cancel = true;
((Form)mdifc).Focus();
break;
}
}
显然,this.MdiChildren表单必须实现ClosableMDIChildForm接口。决定关闭窗口是否可行的逻辑在于IsOkToClose()的实现。