关闭所有打开的窗体,C#中的主菜单除外
本文关键字:菜单 窗体 | 更新日期: 2023-09-27 18:21:38
尝试使用关闭除主菜单外的所有表单
FormCollection formsList = Application.OpenForms;
用foreach循环说,
if (thisForm.Name != "Menu") thisForm.Close();
哪个工作正常,它跳过菜单,关闭第一个,但随后出错:
集合已修改;枚举操作可能无法执行
并停止。我试过几个地方,他们都说foreach循环是实现这一点的方法,这尤其令人讨厌,因为我在关闭表单后没有更新表单列表,我认为这可能会奏效。我唯一能想到的就是从后场开始,利用一段时间向前推进。
如果使用foreach枚举集合,则在迭代过程中无法对其进行修改(添加或删除项)。请尝试将对表单的引用复制到另一个集合,然后通过迭代该集合来删除它们。
在这种情况下,您可以使用列表或简单数组,例如:
List<Form> openForms = new List<Form>();
foreach (Form f in Application.OpenForms)
openForms.Add(f);
foreach (Form f in openForms)
{
if (f.Name != "Menu")
f.Close();
}
或者你可以使用for循环:
for (int i = Application.OpenForms.Count - 1; i >= 0; i--)
{
if (Application.OpenForms[i].Name != "Menu")
Application.OpenForms[i].Close();
}
或者,我的新的和当前的最爱,你可以使用Reverse()方法:
foreach (Form f in Application.OpenForms.Reverse())
{
if (f.Name != "Menu")
f.Close();
}
这里有一个更简洁的方法,它使用与原始方法相同的行数:
Form[] forms = Application.OpenForms.Cast<Form>().ToArray();
foreach (Form thisForm in forms)
{
if (thisForm.Name != "Menu") thisForm.Close();
}
通过使用Linq的扩展方法Cast
,可以避免循环遍历集合来构建数组。
当在使用集合的foreach循环内更改集合时,就会发生这种情况。您正在从循环内的formsList
中删除一个项。
试试这个:
for (int i = formsList.Count-1; i > 0; i--)
{
if (formsList[i].Name != "Menu")
{
formsList[i].Close();
}
}
关闭所有表单:
for (int i = Application.OpenForms.Count - 1; i >= 0; i--)
{
if (Application.OpenForms[i].Name != "Menu")
Application.OpenForms[i].Close();
}
我知道这是旧的,但我需要执行同样的场景,并想出了一种优雅而简单的方法来实现这一点,如下
Form[] formsList = Application.OpenForms.Cast<Form>().Where(x => x.Name == "Form1").ToArray();
foreach (Form openForm in formsList)
{
openForm.Close();
}
这将关闭所有打开的名为Form1 的窗口
由于错误状态,您无法在其foreach中修改集合。
相反,您可以使用向后的for
循环。
因为表单集合在每次迭代中都在更新。关闭表单时,它将从表单集合中删除。这就像在使用时从内存中删除一个对象。