2008-12-19 8 views
17

Aparece el siguiente error al intentar recorrer un cuadro de lista y luego quitar el elemento.¿Cómo recorro los elementos en un cuadro de lista y luego los quito?

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 quitar el elemento y todavía recorren el contenido?

Respuesta

35

¿Desea eliminar todos los elementos? Si es así, primero haga el foreach, luego simplemente use Items.Clear() para eliminarlos todos después.

De lo contrario, tal vez bucle hacia atrás por el 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(); 
} 
+0

Me gustaría ** saber ** de qué se trata ese voto indirecto !! –

+0

Yo también Marc. +1 para contrarrestar la injusticia de la misma. –

+0

Me encantaría saber el motivo de los votos a favor.¡Tanto para ti como para ti! +1 –

1

Tienes que ir a través de la colección desde el último elemento de la primera. este código está en vb

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

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

Aquí es el equivalente C#:

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

¡Ya sabemos todo eso! ¿Por qué te repites? – Fandango68

+0

@ Fernando68 Porque en 2008, hubo personas que no pueden traducir de VB a C#: D –

23

todos los demás han publicado "ir hacia atrás" como respuesta, así que voy a dar la alternativa: crear una lista de elementos que desea eliminar y luego retirarlos al final :

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

a veces el método de "trabajar hacia atrás" es mejor, a veces lo anterior es mejor - especialmente si usted está tratando con un tipo que tiene un método RemoveAll(collection). Vale la pena conocer ambos sin embargo.

+2

-1. listBox1.Items puede contener objetos que no sean de cadena, en ese caso se lanzará InvalidCastException. –

+8

Si ese fuera el caso, el ciclo foreach en el código de ejemplo en la pregunta ya habría explotado. Estaba haciendo la misma suposición que la pregunta, que creo que es bastante razonable. –

+1

Sí, lo noté. Fue divertido rechazarte por una razón durante unos minutos;) –

11

Aquí mi solución sin tener que 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); 
} 
+0

+1 Esto es correcto! – Edyn

+1

@ Fernando68 a medida que disminuye el conteo de ListBox cada vez que se elimina un elemento, la condición de tiempo eventualmente igualará a falsa y el ciclo finalizará. –

1

¿Qué tal:

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 acerca Cambiando la lista mientras la procesas.

0

No se puede modificar la colección que se itera dentro del bloque ForEach.

Una solución rápida consiste en repetir 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) 

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

1

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

Cuestiones relacionadas