如何循环遍历列表框中的项目并删除这些项目?

23

尝试循环遍历 ListBox 并删除其中的项时,我遇到了如下错误:

绑定到此枚举器的列表已被修改。只有在列表不发生更改时,才能使用枚举器。

foreach (string s in listBox1.Items)
{
    MessageBox.Show(s);
    //do stuff with (s);
    listBox1.Items.Remove(s);
}

我该如何在保持循环内容不变的情况下删除其中的一个元素?

8个回答

40

你想要删除所有项目吗?如果是这样,请先使用foreach,然后只需使用Items.Clear()来删除它们。

否则,也许可以通过索引器倒序循环:

listBox1.BeginUpdate();
try {
  for(int i = listBox1.Items.Count - 1; i >= 0 ; i--) {
    // do with listBox1.Items[i]

    listBox1.Items.RemoveAt(i);
  }
} finally {
  listBox1.EndUpdate();
}

我也一样,Marc。+1 来抵消这不公正的行为。 - Binary Worrier
我很想知道downvotes的原因,无论是针对我还是你!+1 - Mehrdad Afshari
@Binary Worrier:实际上,由于200点声望限制,赞成票并不能真正抵消反对票。 - Mehrdad Afshari
@MehrdadAfshari 但是它们确实中和了它们对答案分数的负面影响。+1! :) - Rufus L

26

其他人都已经回答了“向后遍历”的方法,我来提供另一种方法:创建一个要删除的项目列表,然后在最后将它们全部删除:

List<string> removals = new List<string>();
foreach (string s in listBox1.Items)
{
    MessageBox.Show(s);
    //do stuff with (s);
    removals.Add(s);
}

foreach (string s in removals)
{
    listBox1.Items.Remove(s);
}
有时候“倒退”方法更好,有时候上述方法更好-特别是当你处理一个具有RemoveAll(collection)方法的类型时。不过了解两种方法都是值得的。

3
listBox1.Items可能包含除字符串以外的对象,如果是这样的话,将会抛出InvalidCastException异常。 - Mehrdad Afshari
9
如果那是真的,问题中样例代码中的foreach循环早已崩溃了。我和问题提出者做出了相同的假设,我认为这是相当合理的。 - Jon Skeet
1
是的,我注意到了。只是因为某个原因而在一分钟内给你点了踩,感觉很有趣 ;) - Mehrdad Afshari
至少你给了一个理由 :) - Jon Skeet
有一天,我的声望将超过Jons和Mehdrad的总和。嘿嘿嘿!当然,假设人们需要给出下投票的理由。 - Hamish Grubijan

12

这是我的解决方案,不需要回到过去,也不需要临时列表。

while (listBox1.Items.Count > 0)
{
  string s = listBox1.Items[0] as string;
  // do something with s
  listBox1.Items.RemoveAt(0);
}

1
由于每次删除一个项目时 ListBox 的计数会减少,因此 while 条件最终将等于 false 并且循环将结束。 - Michael Murphy

2

while(listbox.Items.Remove(s)) ;应该也可以正常工作。不过,我认为倒序的解决方案是最快的。


2

您需要从最后一个项目开始遍历集合。此代码使用VB编写。

for i as integer= list.items.count-1 to 0 step -1
....
list.items.removeat(i)
next

2

杰斐逊是正确的,你必须倒过来做。

这是C#的等效代码:

for (var i == list.Items.Count - 1; i >= 0; i--)
{
    list.Items.RemoveAt(i);
}

@Fernando68 因为在2008年,有些人无法将VB翻译成C# :D - Jon Limjap

2
如何考虑:
foreach(var s in listBox1.Items.ToArray())
{
    MessageBox.Show(s);
    //do stuff with (s);
    listBox1.Items.Remove(s);
}

ToArray方法会复制列表,因此在处理列表时您不必担心它会更改列表。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接