在 C# 中关闭除主菜单之外的所有打开的表单
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9029351/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Close all open forms except the main menu in C#
提问by Ryan Durrant
Trying to close all forms except for the main menu using
尝试关闭除主菜单之外的所有表单使用
FormCollection formsList = Application.OpenForms;
with a foreach loop and saying,
用 foreach 循环说,
if (thisForm.Name != "Menu") thisForm.Close();
Which works ok, it skips the menu, and closes the first, but it then errors:
哪个工作正常,它跳过菜单,并关闭第一个,但随后出现错误:
Collection was modified; enumeration operation may not execute
集合被修改;枚举操作可能不会执行
and stops. I have tried a few places, and they all say that this foreach loop is the way to do it, and it is especially annoying as I am not updating my forms list after closing the forms, which I thought might work. The only thing I could think of was to start at the back and work forward using a while.
并停止。我已经尝试了几个地方,他们都说这个 foreach 循环是这样做的,它特别烦人,因为我在关闭表单后没有更新我的表单列表,我认为这可能有效。我唯一能想到的就是从后面开始,然后用一段时间向前推进。
采纳答案by Trevor Elliott
If you use foreach to enumerate through a collection, it can't be modified (items added or removed) during the iteration. Try copying references to the forms to another collection, and then remove them by iterating through that collection.
如果您使用 foreach 来枚举一个集合,则在迭代期间不能对其进行修改(添加或删除项目)。尝试将表单引用复制到另一个集合,然后通过迭代该集合来删除它们。
In situations like this, you can use a list or a simple array, such as:
在这种情况下,您可以使用列表或简单数组,例如:
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();
}
Or you can use a for loop:
或者您可以使用 for 循环:
for (int i = Application.OpenForms.Count - 1; i >= 0; i--)
{
if (Application.OpenForms[i].Name != "Menu")
Application.OpenForms[i].Close();
}
Or, my new and current favorite, you can use the Reverse() method:
或者,我新的和当前最喜欢的,您可以使用 Reverse() 方法:
foreach (Form f in Application.OpenForms.Reverse())
{
if (f.Name != "Menu")
f.Close();
}
回答by annonymously
That happens when the collection is changed inside a foreach loop that uses it. You are removing an item from formsListinside the loop.
当在使用它的 foreach 循环内更改集合时,就会发生这种情况。您正在从formsList循环内部删除一个项目。
Try this:
尝试这个:
for (int i = formsList.Count-1; i > 0; i--)
{
if (formsList[i].Name != "Menu")
{
formsList[i].Close();
}
}
回答by SLaks
As the error states, you can't modify a collection in its foreach.
正如错误所述,您无法在其 foreach 中修改集合。
Instead, you can use a backwards forloop.
相反,您可以使用向后for循环。
回答by Ravi Gadag
as the form collection is updating for every iteration. When you close a form, it is removed from the form collection. it's like removing a object from memory while it is using .
因为每次迭代都会更新表单集合。当您关闭表单时,它会从表单集合中删除。这就像在使用 .
回答by Abraham
Here's an even more concise method that uses the same number of lines as your original method:
这是一个更简洁的方法,它使用与原始方法相同的行数:
Form[] forms = Application.OpenForms.Cast<Form>().ToArray();
foreach (Form thisForm in forms)
{
if (thisForm.Name != "Menu") thisForm.Close();
}
By using Linq's extension method Cast, you can avoid looping through the collection to build an array.
通过使用 Linq 的扩展方法Cast,可以避免循环遍历集合来构建数组。
回答by sulaiman
Collection was modified; enumeration operation may not execute.
集合被修改;枚举操作可能无法执行。
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();
回答by maneesh
To Close all forms :
关闭所有表格:
for (int i = Application.OpenForms.Count - 1; i >= 0; i--)
{
if (Application.OpenForms[i].Name != "Menu")
Application.OpenForms[i].Close();
}
回答by Darren Lawrence
I know this is old but I needed to perform this same scenario and came up with a elegant and simple way to achieve this as follows
我知道这很旧,但我需要执行相同的场景,并想出了一种优雅而简单的方法来实现这一点,如下所示
Form[] formsList = Application.OpenForms.Cast<Form>().Where(x => x.Name == "Form1").ToArray();
foreach (Form openForm in formsList)
{
openForm.Close();
}
This will close ALL windows that where opened called Form1
这将关闭所有打开的名为 Form1 的窗口

