尝试循环遍历 ListBox 并删除其中的项时,我遇到了如下错误:
绑定到此枚举器的列表已被修改。只有在列表不发生更改时,才能使用枚举器。
foreach (string s in listBox1.Items)
{
MessageBox.Show(s);
//do stuff with (s);
listBox1.Items.Remove(s);
}
我该如何在保持循环内容不变的情况下删除其中的一个元素?
你想要删除所有项目吗?如果是这样,请先使用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();
}
其他人都已经回答了“向后遍历”的方法,我来提供另一种方法:创建一个要删除的项目列表,然后在最后将它们全部删除:
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)
方法的类型时。不过了解两种方法都是值得的。这是我的解决方案,不需要回到过去,也不需要临时列表。
while (listBox1.Items.Count > 0)
{
string s = listBox1.Items[0] as string;
// do something with s
listBox1.Items.RemoveAt(0);
}
while(listbox.Items.Remove(s)) ;
应该也可以正常工作。不过,我认为倒序的解决方案是最快的。
您需要从最后一个项目开始遍历集合。此代码使用VB编写。
for i as integer= list.items.count-1 to 0 step -1
....
list.items.removeat(i)
next
杰斐逊是正确的,你必须倒过来做。
这是C#的等效代码:
for (var i == list.Items.Count - 1; i >= 0; i--)
{
list.Items.RemoveAt(i);
}
foreach(var s in listBox1.Items.ToArray())
{
MessageBox.Show(s);
//do stuff with (s);
listBox1.Items.Remove(s);
}
ToArray方法会复制列表,因此在处理列表时您不必担心它会更改列表。
在ForEach块中,您不能对正在迭代的集合进行修改。
一个快速的解决方法是遍历集合的副本。通过ArrayList构造函数轻松地创建此副本。复制集合中的DataRowView对象将引用并能够修改与您的代码相同的基础数据。
For Each item As DataRowView In New System.Collections.ArrayList(lbOrdersNeedToBeVoided.Items)