简体   繁体   English

C#一次删除多个按钮

[英]C# Deleting multiple buttons at once

I'm using C# in Microsoft Visual Studio 2012. I have a program where I create a set of buttons on the fly, all are assigned the same event handler. 我在Microsoft Visual Studio 2012中使用C#。我有一个程序,可以在其中动态创建一组按钮,所有按钮都分配有相同的事件处理程序。 (Fancy way for the user to choose an option.) Once this option is chosen I need to destroy all these buttons. (用户选择选项的简便方法。)选择此选项后,我需要销毁所有这些按钮。 I have been using the following code: 我一直在使用以下代码:

 foreach (Control c in this.Controls)
 {
     if (c.GetType() == typeof(Button))
     {
         c.Click -= new EventHandler(TeamChoiceButton_Click);
         this.Controls.Remove(c);
         c.Dispose();
    }
}

The problem is it is deleting every other button. 问题是它正在删除所有其他按钮。 I'm assuming since I'm deleting them inside the foreach, its adjusting the index so its making it skip every other one. 我假设因为要在foreach中删除它们,所以它会调整索引,以使其跳过其他所有索引。 What is the proper way to do this? 正确的方法是什么? Any help would be appreciated, especially if I'm misunderstanding why its skipping every other button. 任何帮助将不胜感激,尤其是如果我误解了为什么跳过其他所有按钮。

Add a value to the Tag property of the buttons in order to mark them for a later deletion. 在按钮的Tag属性中添加一个值,以标记它们以便以后删除。

var btn = new Button();
btn.Tag = new object();
btn.Text = "xy";
...
this.Control.Add(btn);

Then you can remove them with: 然后,您可以使用以下方法删除它们:

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 queries are executed in a lazy way. LINQ到对象的查询以惰性方式执行。 This means that the query is evaluated as the foreach-loop is going on, if we don't add a .ToList() to the query. 这意味着如果我们不向查询中添加.ToList() ,则会在foreach循环进行时对查询进行评估。 Deleting controls from the Controls collection while the Controls collection is enumerated would throw an exception. 删除从控制Controls集合,而Controls集合枚举会抛出异常。 .ToList() forces a premature evaluation of the query, thus eliminating the problem. .ToList()强制对查询进行过早评估,从而消除了该问题。

You can iterate over the list backwards and remove the items that way: 您可以向后遍历列表,并通过以下方式删除项目:

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();
    }
}

you can put all the button you create on the fly into a List<Button> when you create it then use : 您可以将创建的所有按钮即时创建到List<Button> ,然后使用:

foreach (Button b in myButtonList)
{
    this.Controls.Remove(b);
}
myButtonList.Clear();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM