2010-05-10 183 views
0

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

到目前为止很好,但是我发现关闭MDI主窗体不会引发MDI子FormClosing事件。我想我会在MDI main的FormClosing事件中调用MdiChild。Close()(它会得到提升)。这接缝工作,但它确实造成问题...

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

编辑:我解决了这个问题,通过抛出异常(当用户决定取消关闭过程时),它在MDI main的FormClosing事件中被捕获。通过这种方式,我知道什么时候我必须取消MDI主窗体的FormClosing事件,并且这种接缝工作正常......但我简直不敢相信这个“​​hax”是这样做的唯一方式。当然有更好的方法?

回答

2

我觉得当用户投票取消关闭时,你取消了关于childform的关闭?

在这种情况下,我与关闭这个主要形式去

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); 
} 
+0

不,不要这样做,因为您可能希望在用户在“保存更改”提示中点击取消时立即停止。您不希望用户必须在此处循环查看每个表单,并且此代码执行此操作。相反,在调用Close()之后,请检查frm.IsDisposed。如果它是错误的,表单由于某种原因无法关闭,您应该设置e.Cancel = true并从您的foreach循环中断开。这样一旦用户点击取消,整个操作就会停止。 – 2013-08-26 16:30:43

1

我建议您不要在子表单上调用Close,而是在子表单中创建一个像ReadyToClose这样的方法,然后主窗体循环并调用每个子窗体的方法,然后它会问这个问题给用户并在需要时进行保存,最后如果可以继续则返回true。

如果所有的孩子形成“投票”结束,那么你关闭它,否则你什么都没有关闭。

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()的实现中进行。