我希望你能帮助我解决这个问题。我的应用程序正在监视数据库中的警报。当数据库中出现警报时,我的应用程序会将其添加到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();
我希望有人能有一些好主意如何解决这个问题。我已经搜索过但不能真正找到一种简单而优雅的方法来做到这一点。
答案 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();
}