如果用户以某种方式关闭主窗体,我需要确保所有窗体都将关闭。所以我决定隐藏Close()函数,我写了这样的东西
public new bool Close()
{
List<Form> formsList = new List<Form>(Application.OpenForms.Count);
foreach (var form in Application.OpenForms)
formsList.Add((Form)form);
formsList.Reverse();
foreach (var form in formsList)
{
if (form.IsDisposed) continue;
Invoke(new GenericEventHandler(() => { form.Close(); }));
}
return Application.OpenForms.Count == 0;
}
因此,如果所有表单都已成功关闭,我将返回true,并且由于这一点,我知道用户可以从应用程序注销。
然而,似乎不会立即触发form.Close()函数。调用form.Close()
后,不立即触发formclosed事件以及集合Application.OpenForms未被修改。已更改已打开表单的数量。
可能是什么原因?
答案 0 :(得分:5)
为什么不使用
Application.Exit();
答案 1 :(得分:1)
如果主窗体是通过Application.Run(new MainForm());
在WinForms中以标准方式创建的,那么当它关闭时,应用程序将退出,关闭所有其他窗体。因此,我认为您不必担心手动关闭所有子表单。
答案 2 :(得分:1)
好吧,如果用户关闭了主表单,那么一旦关闭它,您的应用程序肯定会退出,因为您的表单负责在应用程序传递给Application.Run()时保持应用程序处于活动状态
现在,如果您想在关闭 表单时关闭应用,请执行以下操作:
protected override void OnFormClosed(FormClosedEventArgs e)
{
base.OnFormClosed(e);
Application.Exit();
}
答案 3 :(得分:0)
一般情况下,我建议不要对Control和/或Form类的任何成员使用new关键字。如果您需要自己的方法,请使用自己的名称。
在代码中,关闭子表单时不需要使用Invoke。
如果您需要确保在实际执行与MainForm.Close相关的逻辑之前关闭了所有子窗体,您可以使用类似于下面的处理程序订阅MainForm.FormClosing事件:
void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
bool allChildFormsClosed = !closeAllChildForms();
if(!allChildFormsClosed)
{
e.Cancel = true;
MessageBox.Show("Failed to close one or more child forms.");
// better add some yes|no dialog to force exit if necessary
}
}
您可以用与上面类似的方式实现closeAllChildForms - 只需:删除formsList.Reverse();和'Invoke ..' - 直接调用Close并更新:if(this == form || form.IsDisposed)continue;
答案 4 :(得分:0)
如果由于某种原因,Application.Exit没有为您剪切,您可以尝试此代码(将其放在表单的FormClosing事件中):
while (Application.OpenForms.Count > 1)
{
Form form = Application.OpenForms[1];
form.Close();
while (!form.IsDisposed) Application.DoEvents();
}
或者如果你想让它在一段时间后无法关闭所有表格时超时,
while (Application.OpenForms.Count > 1)
{
Form form = Application.OpenForms[1];
form.Close();
DateTime StartTime = DateTime.Now;
while (!form.IsDisposed && (StartTime - DateTime.Now).TotalMilliseconds < 1000)
Application.DoEvents(); //1-second timeout here
if (!form.IsDisposed) //if it's still not closed
{
//send a message to the user that the application can't exit right now
mbox("some forms are still open or whatever");
e.Cancel = true;
return;
}
}