2012-01-27 15 views
13

试图关闭所有形式除了使用关闭所有打开的形式,除了在C#中的主菜单

FormCollection formsList = Application.OpenForms; 

与foreach循环,并说在主菜单中,

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

其中工程确定,它跳过菜单,并关闭第一个,但它然后错误:

集合被修改;枚举操作可能不会执行

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

回答

53

如果您使用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(); 
} 
+5

给他人的提示 - Reverse似乎无法在.NET中使用框架4。 – 2015-01-17 15:18:32

2

集合在使用它的foreach循环内发生更改时发生。您正在从循环中删除formsList中的项目。

试试这个:

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

由于错误状态,你不能在它的foreach修改的集合。

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

0

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

2

下面是一个使用相同数量的李更简捷的方法网元作为原始的方法:

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

使用LINQ的扩展方法Cast,就可以避免通过收集循环来构建一个数组。

0

收藏被修改;枚举操作可能不会执行。

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(); 
2

要关闭所有形式:

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

我知道这是旧的,但我需要执行此相同的情况下,用优雅和简单的方式实现这一目标如下

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

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