可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm getting the error below when trying to loop through a listbox and then remove the item.
List that this enumerator is bound to has been modified. An enumerator can only be used if the list does not change.
foreach (string s in listBox1.Items)
{
MessageBox.Show(s);
//do stuff with (s);
listBox1.Items.Remove(s);
}
How can I remove the item and still loop through the contents?
回答1:
Do you want to remove all items? If so, do the foreach
first, then just use Items.Clear()
to remove all of them afterwards.
Otherwise, perhaps loop backwards by indexer:
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();
}
回答2:
Everyone else has posted "going backwards" answer, so I'll give the alternative: create a list of items you want to remove, then remove them at the end:
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);
}
Sometimes the "work backwards" method is better, sometimes the above is better - particularly if you're dealing with a type which has a RemoveAll(collection)
method. Worth knowing both though.
回答3:
Here my solution without going backward and without a temporary list
while (listBox1.Items.Count > 0)
{
string s = listBox1.Items[0] as string;
// do something with s
listBox1.Items.RemoveAt(0);
}
回答4:
You have to go through the collection from the last item to the first. this code is in vb
for i as integer= list.items.count-1 to 0 step -1
....
list.items.removeat(i)
next
回答5:
Jefferson is right, you have to do it backwards.
Here's the c# equivalent:
for (var i == list.Items.Count - 1; i >= 0; i--)
{
list.Items.RemoveAt(i);
}
回答6:
How about:
foreach(var s in listBox1.Items.ToArray())
{
MessageBox.Show(s);
//do stuff with (s);
listBox1.Items.Remove(s);
}
The ToArray makes a copy of the list, so you don't need to worry about it changing the list while you are processing it.
回答7:
while(listbox.Items.Remove(s)) ;
should work, as well. However, I think the backwards solution is the fastest.
回答8:
You can't make modification to the collection being iterated within the ForEach block.
A quick fix is to iterate over a copy of the collection. An easy way to make this copy is through the ArrayList constructor. The DataRowView objects in the copied collection will refer to, and be able to modify, the same underlying data as your code.
For Each item As DataRowView In New System.Collections.ArrayList(lbOrdersNeedToBeVoided.Items)
please read http://social.msdn.microsoft.com/Forums/en-AU/vbgeneral/thread/b4d1f649-d78a-4e5b-8ad8-1940e3379bed