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