¿Cómo recorro los elementos en un cuadro de lista y luego elimino esos elementos?

Recibo el siguiente error al intentar recorrer un cuadro de lista y luego eliminar el elemento.

La lista a la que está obligado este enumerador ha sido modificada. Un enumerador solo puede usarse si la lista no cambia.

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

¿Cómo puedo eliminar el elemento y seguir recorriendo los contenidos?

¿Quieres eliminar todos los elementos? Si es así, primero haz lo foreach , luego usa Items.Clear() para eliminarlos todos después.

De lo contrario, quizás retroceda por indexador:

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

Todos los demás han publicado la respuesta “yendo hacia atrás”, así que les daré la alternativa: crear una lista de elementos que desea eliminar y luego eliminarlos al final:

 List removals = new List(); 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); } 

A veces, el método “trabajar hacia atrás” es mejor, a veces lo anterior es mejor, especialmente si se trata de un tipo que tiene un método RemoveAll(collection) . Vale la pena conocer ambos sin embargo.

Aquí mi solución sin ir hacia atrás y sin una lista temporal

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

Tienes que pasar por la colección desde el último elemento hasta el primero. este código está en vb

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

Jefferson tiene razón, tienes que hacerlo al revés.

Aquí está el equivalente de c #:

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

Qué tal si:

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

El ToArray hace una copia de la lista, por lo que no tiene que preocuparse porque cambie la lista mientras la está procesando.

while(listbox.Items.Remove(s)) ; debería funcionar, también. Sin embargo, creo que la solución al revés es la más rápida .

No puede realizar modificaciones en la colección que se itera dentro del bloque ForEach.

Una solución rápida es iterar sobre una copia de la colección. Una forma fácil de hacer esta copia es a través del constructor ArrayList. Los objetos DataRowView en la colección copiada se referirán a, y podrán modificar, los mismos datos subyacentes que su código.

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

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