C#一次删除多个按钮

时间:2014-03-29 21:28:26

标签: c#

我在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中删除它们,它调整索引使它使其跳过其他每一个。这样做的正确方法是什么?任何帮助都会受到赞赏,特别是如果我误解了为什么它会跳过其他按钮。

3 个答案:

答案 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();