我在Microsoft Visual Studio 2012中使用C#。 我有一个程序,我在其中创建一组按钮,所有按钮都分配了相同的事件处理程序。 (用户选择选项的奇特方式。)选择此选项后,我需要销毁所有这些按钮。我一直在使用以下代码:
foreach (Control c in this.Controls)
{
if (c.GetType() == typeof(Button))
{
c.Click -= new EventHandler(TeamChoiceButton_Click);
this.Controls.Remove(c);
c.Dispose();
}
}
问题是它是否正在删除所有其他按钮。我假设,因为我在foreach中删除它们,它调整索引使它使其跳过其他每一个。这样做的正确方法是什么?任何帮助都会受到赞赏,特别是如果我误解了为什么它会跳过其他按钮。
答案 0 :(得分:4)
为按钮的Tag
属性添加一个值,以便将其标记为以后删除。
var btn = new Button();
btn.Tag = new object();
btn.Text = "xy";
...
this.Control.Add(btn);
然后你可以用以下方法删除它们:
var myButtons = this.Controls
.OfType<Button>()
.Where(b => b.Tag != null)
.ToList(); //Because you cannot modify the collection being iterated with for each.
foreach (Button b in myButtons) {
b.Click -= new EventHandler(TeamChoiceButton_Click);
this.Controls.Remove(b);
b.Dispose();
}
LINQ-to-object查询以惰性方式执行。这意味着如果我们不在查询中添加.ToList()
,则会在foreach循环开始时评估查询。枚举Controls
集合时从Controls
集合中删除控件会引发异常。 .ToList()
强制过早评估查询,从而消除问题。
答案 1 :(得分:3)
您可以向后迭代列表并以这种方式删除项目:
for (int i = this.Controls.Count - 1; i >= 0; i--)
{
Control c = this.Controls[i];
if (c.GetType() == typeof (Button))
{
c.Click -= new EventHandler(TeamChoiceButton_Click);
this.Controls.RemoveAt(i);
c.Dispose();
}
}
答案 2 :(得分:2)
您可以在创建时将您创建的所有按钮放入List<Button>
然后使用:
foreach (Button b in myButtonList)
{
this.Controls.Remove(b);
}
myButtonList.Clear();