C#在多表单应用程序中关闭特定表单

时间:2011-11-23 11:51:57

标签: c# winforms

我希望你能帮助我解决这个问题。我的应用程序正在监视数据库中的警报。当数据库中出现警报时,我的应用程序会将其添加到datagridview中的主窗体中,并且根据其优先级,它还将为事件创建一个小的winform弹出窗口。

在datagridview中有一个按钮,用于将警报标记为“已见”,然后它将更新数据库,并且它将从列表中消失。但是,此活动的弹出窗体仍处于打开状态。

有谁知道如何关闭此表单?我需要一种方法来查找可能的多个警报表单之间的特定表单。

我到目前为止最接近的是以下代码:

private void closeForm(int id)
{
    foreach (Form f in Application.OpenForms)
    {
        if (Convert.ToString(id) == f.Name)
        {
            this.Close();
        }
    }
}

直到它关闭正确的形式为止。然后它给出了一个错误,说“集合被修改;枚举操作可能无法执行。”这种方法有道理,但我根本无法找到另一种方法。

我有一个名为Alert的winform类,它创建了新的表单。如您所见,他们将获得标准文本“警报”和基于警报ID的唯一名称。

Alert alertform = new Alert(id);
alertform.Name = formid;
alertform.Text = "Alarm";
alertform.Show();

我希望有人能有一些好主意如何解决这个问题。我已经搜索过但不能真正找到一种简单而优雅的方法来做到这一点。

6 个答案:

答案 0 :(得分:4)

您应该只需在DataGridView或其DataSource中存储对表单的引用,然后使用该引用关闭表单。这种方法在未来不太可能比在所有应用程序表单上进行迭代。

最有效的方法是将隐藏列添加到包含表单ID的DataGridView,然后还有一个Dictionary<int, Form>,用于获取对要关闭的表单的引用

然后你可以简单地从字典中获取表单引用并在其上调用close:

private void CloseAlertForm(int id)
{        
    Form f = dict[id];
    f.Close();
    dict.Remove(id);
}

此外,您可以存储Action个代表而不是表单引用,从而允许您稍微分离警报表单和网格表单。

答案 1 :(得分:4)

你需要添加休息;关闭表单后进入循环。当您关闭表单(该表单从集合中删除)时,将修改该集合,从而使foreach循环无效。如果你不是在调用f.Close而不是this.Close?

private void closeForm(int id)

    {
        foreach (Form f in Application.OpenForms)

            if (Convert.ToString(id) == f.Name)
            {
                f.Close();
                break;

            }
    }

答案 2 :(得分:3)

得到参考。从foreach循环并关闭它外面的form

private void closeForm(int id)
{   
        Form formtoclose=null;
        foreach (Form f in Application.OpenForms)
        {
            if (Convert.ToString(id) == f.Name)
            {
                formtoclose = f;
            }
        }
        if(formtoclose!=null)
        formtoclose.Close();
}

答案 3 :(得分:-1)

关闭会修改您的OpenForms集合,因此您可以直接枚举OpenForms集合而不是枚举。

LINQ非常方便制作副本,如下所示:

foreach (Form f in Application.OpenForms.Where(i => Convert.ToString(id) == i.Name).ToList()) {
      // Save to close the form here
}

ToList执行查询,并存储副本。

答案 4 :(得分:-2)

您可以使用表单的类型来查找它们(并ToArray创建一个新集合,避免更改您要枚举的集合。)

private void CloseAlerts()
{
    var openForms = Application.OpenForms.Cast<Form>();
    foreach (var f in openForms.Where(f => f is Alert).ToArray())
    {
        f.Close();
    }
}

在这种情况下,您无需设置名称:

Alert alertform = new Alert(id);

alertform.Text = "Alarm";

alertform.Show();

答案 5 :(得分:-2)

var names = Application.OpenForms.Select(rs=>rs.name).ToList()

foreach (string name in names)
    if (Convert.ToString(id) == name)
    {
        Application.OpenForms[name].Close();
    }