Wie durchlaufe ich Elemente in einem Listenfeld und entferne diese Elemente dann?

Ich erhalte den Fehler unten, wenn ich versuche, ein Listenfeld durchzulaufen und das Element dann zu entfernen.

Die Liste, an die dieser Enumerator gebunden ist, wurde geändert. Ein Enumerator kann nur verwendet werden, wenn sich die Liste nicht ändert.

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

Wie kann ich den Artikel entfernen und trotzdem den Inhalt durchgehen?

   

    Möchten Sie alle Elemente entfernen? Wenn ja, mach zuerst die foreach , dann benutze Items.Clear() , um sie alle danach zu entfernen.

    Andernfalls, vielleicht rückwärts durch den 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(); } 

    Alle anderen haben die Antwort “going backwards” gepostet, also gebe ich die Alternative: Erstelle eine Liste von Elementen, die du entfernen möchtest, und entferne sie dann am Ende:

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

    Manchmal ist die “rückwärts arbeiten” -Methode besser, manchmal ist das obige besser – besonders wenn Sie mit einem Typ arbeiten, der eine RemoveAll(collection) Methode RemoveAll(collection) . Gut zu wissen aber beide.

    Hier meine Lösung ohne Rückwärtsgehen und ohne eine temporäre Liste

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

    Sie müssen die Sammlung vom letzten Artikel bis zum ersten durchlaufen. Dieser Code ist in Vb

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

    Jefferson hat Recht, du musst es rückwärts machen.

    Hier ist das c # Äquivalent:

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

    Wie wäre es mit:

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

    Das ToArray erstellt eine Kopie der Liste, sodass Sie sich keine Sorgen darüber machen müssen, dass die Liste während der Verarbeitung geändert wird.

    while(listbox.Items.Remove(s)) ; sollte auch funktionieren. Ich denke jedoch, dass die Rückwärtslösung die schnellste ist .

    Sie können keine Änderungen an der Sammlung vornehmen, die im ForEach-Block wiederholt wird.

    Eine schnelle Lösung besteht darin, über eine Kopie der Sammlung zu iterieren. Eine einfache Möglichkeit, diese Kopie zu erstellen, ist der ArrayList-Konstruktor. Die DataRowView-Objekte in der kopierten Sammlung beziehen sich auf dieselben zugrunde liegenden Daten wie Ihr Code und können dieselben ändern.

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

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