C#一次删除多个按钮

C#一次删除多个按钮,c#,C#,我在Microsoft Visual Studio 2012中使用C#。 我有一个程序,在这个程序中,我动态地创建了一组按钮,所有按钮都被分配了相同的事件处理程序。(用户选择选项的奇特方式。)选择此选项后,我需要销毁所有这些按钮。我一直在使用以下代码: foreach (Control c in this.Controls) { if (c.GetType() == typeof(Button)) { c.Click -= new EventHandle

我在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中删除它们,所以它会调整索引,使其每隔一次跳过一次。正确的方法是什么?任何帮助都将不胜感激,特别是如果我误解了为什么它会跳过其他每个按钮。

您可以在创建按钮时,将您动态创建的所有按钮放入
列表中
然后使用:

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

创建按钮时,您可以将动态创建的所有按钮放入
列表中
然后使用:

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

在按钮的
标记
属性中添加一个值,以便标记它们以便以后删除

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();
}
var myButtons=this.Controls
第()类
.Where(b=>b.Tag!=null)
.ToList()//因为您无法修改正在使用for each进行迭代的集合。
foreach(myButtons中的按钮b){
b、 单击-=新建事件处理程序(TeamChoiceButton\u单击);
此。控制。移除(b);
b、 处置();
}

LINQ到对象查询是以惰性方式执行的。这意味着,如果不向查询中添加
.ToList()
,则在foreach循环进行时对查询求值。当枚举
控件
集合时,从
控件
集合中删除控件将引发异常
.ToList()
强制提前计算查询,从而消除问题。

向按钮的
标记属性添加值,以便标记它们以便以后删除

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();
}
var myButtons=this.Controls
第()类
.Where(b=>b.Tag!=null)
.ToList()//因为您无法修改正在使用for each进行迭代的集合。
foreach(myButtons中的按钮b){
b、 单击-=新建事件处理程序(TeamChoiceButton\u单击);
此。控制。移除(b);
b、 处置();
}

LINQ到对象查询是以惰性方式执行的。这意味着,如果不向查询中添加
.ToList()
,则在foreach循环进行时对查询求值。当枚举
控件
集合时,从
控件
集合中删除控件将引发异常
.ToList()
强制过早计算查询,从而消除问题。

您可以通过以下方式向后迭代列表并删除项目:

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

您可以通过以下方式向后迭代列表并删除项目:

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

将它们放在一个面板中,并在
面板上迭代。控件使用
for
索引到列表中,并从最后一个到第零个进行迭代。当您每隔一个按钮说一次
时,你是说它正在删除你不想删除的按钮,还是说它只删除了一半的按钮?旁注:我希望这段代码只删除第一个按钮,而在下一个元素上失败,因为当元素列表更改时,集合将使迭代器无效…将它们放在面板中,并在
面板上迭代。控件
使用
用于
索引到列表中,并从最后一个迭代到第0个。当您每隔一个按钮说一次
时,你是说它正在删除你不想删除的按钮,还是说它只删除了一半的按钮?旁注:我希望这段代码只删除第一个按钮,并在下一个元素上失败,因为当元素列表发生更改时,集合应该使迭代器失效…谢谢,这完全符合需要(还要感谢安德鲁·莫顿给出的同样的答案。)谢谢这完全符合需要(也要感谢安德鲁·莫顿给出的同样的答案).我最终使用了列表后面的一个迭代,但我想解释一下上面的代码,看看我是否理解它。myButtons变量是this.Controls.和各种.OfType和.Where.Linq函数的一个参考变量,用于操作列表。ToList将其从一个which type Controls(IEnumerable?)更改为一个which type Controls到实际的IList类型。由于我正在迭代引用变量,因此如果我更改数据变量,其索引将不会更改。类型()的控件
其中(…)
是应用于
控件
属性提供的控件枚举的筛选器。不带
ToList()
变量
myButtons
只是一个查询,在
foreach
-语句执行该查询之前,它什么也不做
调用立即执行查询,并将
myButtons
转换为
列表
独立于
控件
集合存储按钮。
OfType()
过滤按钮并将
IEnumerable
转换为
IEnumerable
其中()
调用过滤器按钮设置了它们的
标记
值。我最终使用了列表后面的一个迭代,但我想解释一下上面的代码,看看我是否理解它。myButtons变量是this.Controls的一个参考变量。以及各种.OfType和.Where是用来操作列表的Linq函数将其从控件的任何类型(IEnumerable?)转换为实际的IList类型。由于我正在迭代引用变量,因此如果我更改数据变量this,其索引将不会更改。控件
of type()
Where(…)
是应用于
控件
属性提供的控件枚举的筛选器。如果没有
ToList()
myButtons
变量将只是一个查询,在
foreach
-语句执行该查询之前,该查询不做任何操作。使用
ToList()
调用,查询将被取消