Ben H
Ben H

Reputation:

How do I loop through items in a list box and then remove those item?

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?

Upvotes: 23

Views: 127302

Answers (8)

ThunderGr
ThunderGr

Reputation: 2367

while(listbox.Items.Remove(s)) ; should work, as well. However, I think the backwards solution is the fastest.

Upvotes: 2

Somnath Kadam
Somnath Kadam

Reputation: 6387

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

Upvotes: 0

Matthew Wright
Matthew Wright

Reputation: 199

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.

Upvotes: 2

nruessmann
nruessmann

Reputation: 335

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);
}

Upvotes: 12

Jon Skeet
Jon Skeet

Reputation: 1503509

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.

Upvotes: 26

Jon Limjap
Jon Limjap

Reputation: 95502

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);
}

Upvotes: 2

Jefferson
Jefferson

Reputation:

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

Upvotes: 2

Marc Gravell
Marc Gravell

Reputation: 1064114

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();
}

Upvotes: 40

Related Questions