关闭除C#主菜单以外的所有打开表单

尝试关闭除主菜单之外的所有表单

FormCollection formsList = Application.OpenForms; 

用一个foreach循环说,

 if (thisForm.Name != "Menu") thisForm.Close(); 

哪个工作正常,它跳过菜单,然后关闭第一个,但然后错误:

collections被修改; 枚举操作可能无法执行

并停止。 我已经尝试了几个地方,并且他们都说这个foreach循环是这样做的方式,并且特别令人讨厌,因为我在关闭表单后没有更新我的表单列表,我认为这可能有效。 我唯一能想到的就是从后面开始并使用一段时间前进。

如果使用foreach枚举集合,则在迭代期间无法修改(添加或删除项目)。 尝试将对表单的引用复制到另一个集合,然后通过遍历该集合来删除它们。

在这种情况下,您可以使用列表或简单数组,例如:

 List
openForms = new List
(); 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(); } 

当在使用它的foreach循环内更改集合时会发生这种情况。 您正在循环中从formsList中删除一个项目。

试试这个:

 for (int i = formsList.Count-1; i > 0; i--) { if (formsList[i].Name != "Menu") { formsList[i].Close(); } } 

这是一个更简洁的方法,使用与原始方法相同的行数:

 Form[] forms = Application.OpenForms.Cast
().ToArray(); foreach (Form thisForm in forms) { if (thisForm.Name != "Menu") thisForm.Close(); }

通过使用Linq的扩展方法Cast ,您可以避免循环遍历集合以构建数组。

要关闭所有表格:

  for (int i = Application.OpenForms.Count - 1; i >= 0; i--) { if (Application.OpenForms[i].Name != "Menu") Application.OpenForms[i].Close(); } 

正如错误所述,您无法在其foreach中修改集合。

相反,您可以使用向后循环。

因为表单集合正在为每次迭代进行更新。 关闭表单时,它将从表单集合中删除。 就像在使用时从内存中删除对象一样。

collections被修改; 枚举操作可能无法执行。

 FormCollection formsList = Application.OpenForms; //for (int i = 0; i < formsList.Count; i++) foreach(Form f in formsList ) { if (f.Name != "Form1" || f.Name != "Home" || f.Name != "AdminHome") f.Close(); } this.Close(); 

我知道这是旧的,但我需要执行相同的场景,并提出了一种优雅而简单的方法来实现此目的如下

  Form[] formsList = Application.OpenForms.Cast
().Where(x => x.Name == "Form1").ToArray(); foreach (Form openForm in formsList) { openForm.Close(); }

这将关闭所有打开的窗口,称为Form1