22

尝试遍历列表框然后删除该项目时,出现以下错误。

此枚举器绑定到的列表已被修改。仅当列表不变时才能使用枚举器。

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

如何删除该项目并仍然循环浏览内容?

4

8 回答 8

37

是否要删除所有项目?如果是这样,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();
}
于 2008-12-19T09:15:37.647 回答
25

其他人都发布了“倒退”的答案,所以我会给出另一种选择:创建一个要删除的项目列表,然后在最后删除它们:

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)方法的类型。不过都值得知道。

于 2008-12-19T09:31:59.937 回答
11

这是我的解决方案,没有后退也没有临时列表

while (listBox1.Items.Count > 0)
{
  string s = listBox1.Items[0] as string;
  // do something with s
  listBox1.Items.RemoveAt(0);
}
于 2008-12-19T10:12:12.103 回答
1

您必须从最后一个项目到第一个项目来遍历集合。此代码在 vb 中

for i as integer= list.items.count-1 to 0 step -1
....
list.items.removeat(i)
next
于 2008-12-19T09:18:37.313 回答
1

杰斐逊是对的,你必须倒退。

这是 c# 等价物:

for (var i == list.Items.Count - 1; i >= 0; i--)
{
    list.Items.RemoveAt(i);
}
于 2008-12-19T09:20:55.637 回答
1

怎么样:

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

ToArray 会生成列表的副本,因此您无需担心在处理列表时它会更改列表。

于 2008-12-19T10:12:27.283 回答
1

while(listbox.Items.Remove(s)) ;也应该工作。但是,我认为向后的解决方案是最快的。

于 2013-10-07T09:09:18.187 回答
0

您不能对 ForEach 块中迭代的集合进行修改。

一个快速的解决方法是遍历集合的副本。制作此副本的一种简单方法是通过 ArrayList 构造函数。复制集合中的 DataRowView 对象将引用并能够修改与您的代码相同的基础数据。

For Each item As DataRowView In New System.Collections.ArrayList(lbOrdersNeedToBeVoided.Items)

请阅读http://social.msdn.microsoft.com/Forums/en-AU/vbgeneral/thread/b4d1f649-d78a-4e5b-8ad8-1940e3379bed

于 2013-01-11T09:54:24.133 回答