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

时间:2012-01-27 05:30:28

标签: c# winforms

尝试使用

关闭除主菜单以外的所有表单
FormCollection formsList = Application.OpenForms;

用foreach循环说,

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

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

  

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

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

8 个答案:

答案 0 :(得分:54)

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

答案 1 :(得分:2)

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

试试这个:

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

答案 2 :(得分:2)

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

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

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

答案 3 :(得分:2)

关闭所有表格:

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

答案 4 :(得分:0)

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

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

答案 5 :(得分:0)

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

答案 6 :(得分: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();

答案 7 :(得分:0)

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

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

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