2008-12-19 10 views
17

Ich erhalte den Fehler unten, wenn ich versuche, ein Listenfeld durchzulaufen und dann das Element zu entfernen.Wie kann ich Elemente in einem Listenfeld durchlaufen und diese Elemente dann entfernen?

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 oder noch Schleife durch den Inhalt?

Antwort

35

Möchten Sie alle Elemente entfernen? Wenn dies der Fall ist, tun Sie zuerst die foreach, dann verwenden Sie einfach Items.Clear(), um alle danach zu entfernen.

Ansonsten vielleicht Schleife rückwärts durch 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(); 
} 
+0

Ich würde ** lieben ** zu wissen, worum es bei diesem Downvote geht !! –

+0

Ich auch Marc. +1 gegen die Ungerechtigkeit handeln. –

+0

Ich würde gerne den Grund für Downvotes wissen.Sowohl für mich als auch für dich! +1 –

1

Sie haben mit dem ersten durch die Sammlung aus dem letzten Punkt zu gehen. Dieser Code ist in vb

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

Jefferson ist richtig, Sie müssen es rückwärts tun.

Hier ist die C# -Äquivalent:

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

Das wissen wir schon alles! Warum wiederholst du dich? – Fandango68

+0

@ Fernando68 Da im Jahr 2008 gab es Leute, die nicht von VB zu C# übersetzen können: D –

23

Jeder andere Antwort „nach hinten los“ wurde gebucht, also werde ich die Alternative geben: Erstellen Sie eine Liste der Elemente, die Sie entfernen möchten, entfernen Sie sie dann am Ende :

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

manchmal ist die „Arbeit nach hinten“ Methode besser ist, manchmal über das ist besser - vor allem, wenn Sie mit einer Art zu tun hat, die eine RemoveAll(collection) Methode hat. Gut zu wissen aber beide.

+2

-1. listBox1.Items kann andere Objekte als string enthalten. In diesem Fall wird InvalidCastException ausgelöst. –

+8

Wenn dies der Fall wäre, wäre die foreach-Schleife im Beispielcode in der Frage bereits in die Luft gegangen. Ich habe die gleiche Annahme gemacht wie die Frage, was ich für ziemlich vernünftig halte. –

+1

Ja, ich habe es bemerkt. Es hat einfach Spaß gemacht, dich aus einem bestimmten Grund für eine Minute abzumelden;) –

11

Hier ist meine Lösung ohne rückwärts zu gehen und ohne temporäre Liste

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

+1 Das ist richtig! – Edyn

+1

@ Fernando68 wie die Zählung der ListBox jedes Mal verringert wird, wenn ein Element entfernt wird, wird die While-Bedingung schließlich zu false gleichgesetzt und die Schleife wird beendet. –

1

Wie wäre:

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

Die ToArray eine Kopie der Liste macht, so müssen Sie nicht darum kümmern, Sie ändern die Liste, während Sie sie bearbeiten.

0

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 http://social.msdn.microsoft.com/Forums/en-AU/vbgeneral/thread/b4d1f649-d78a-4e5b-8ad8-1940e3379bed

1

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

Verwandte Themen