J'obtiens l'erreur ci-dessous lorsque j'essaie de parcourir une zone de liste, puis de supprimer l'élément.
Liste à laquelle cet énumérateur est lié a été modifiée. Un énumérateur ne peut être utilisé que si la liste ne change pas.
foreach (string s in listBox1.Items)
{
MessageBox.Show(s);
//do stuff with (s);
listBox1.Items.Remove(s);
}
Comment puis-je supprimer l'élément et continuer à parcourir le contenu?
Voulez-vous supprimer tous les éléments? Si c'est le cas, faites d'abord le foreach
, puis utilisez simplement Items.Clear()
pour les supprimer tous par la suite.
Sinon, bouclez peut-être en arrière par l'indexeur:
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();
}
Tout le monde a posté une réponse "revenir en arrière", je vais donc donner l'alternative: créez une liste des éléments que vous souhaitez supprimer, puis supprimez-les à la fin:
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);
}
Parfois, la méthode "travailler en arrière" est meilleure, parfois ce qui précède est meilleur - en particulier si vous avez affaire à un type qui a une méthode RemoveAll(collection)
. Cela vaut la peine de savoir les deux cependant.
Voici ma solution sans revenir en arrière et sans liste temporaire
while (listBox1.Items.Count > 0)
{
string s = listBox1.Items[0] as string;
// do something with s
listBox1.Items.RemoveAt(0);
}
Vous devez parcourir la collection du dernier article au premier. ce code est en vb
for i as integer= list.items.count-1 to 0 step -1
....
list.items.removeat(i)
next
Jefferson a raison, vous devez le faire à l'envers.
Voici l'équivalent c #:
for (var i == list.Items.Count - 1; i >= 0; i--)
{
list.Items.RemoveAt(i);
}
while(listbox.Items.Remove(s)) ;
devrait également fonctionner. Cependant, je pense que la solution à l'envers est le le plus rapide.
Que diriez-vous:
foreach(var s in listBox1.Items.ToArray())
{
MessageBox.Show(s);
//do stuff with (s);
listBox1.Items.Remove(s);
}
Le ToArray crée une copie de la liste, vous n'avez donc pas à vous soucier de la modification de la liste pendant que vous la traitez.
Vous ne pouvez pas modifier la collection en cours d'itération dans le bloc ForEach.
Une solution rapide consiste à parcourir une copie de la collection. Un moyen simple de faire cette copie est d'utiliser le constructeur ArrayList. Les objets DataRowView de la collection copiée feront référence et pourront modifier les mêmes données sous-jacentes que votre code.
For Each item As DataRowView In New System.Collections.ArrayList(lbOrdersNeedToBeVoided.Items)
veuillez lire http://social.msdn.Microsoft.com/Forums/en-AU/vbgeneral/thread/b4d1f649-d78a-4e5b-8ad8-1940e3379bed