リストボックスをループしてからアイテムを削除しようとすると、次のエラーが表示されます。
この列挙子がバインドされているリストは変更されています。列挙子は、リストが変更されない場合にのみ使用できます。
foreach (string s in listBox1.Items)
{
MessageBox.Show(s);
//do stuff with (s);
listBox1.Items.Remove(s);
}
どうすればアイテムを削除してもコンテンツをループできますか?
すべてのアイテムを削除しますか?その場合は、最初にforeach
を実行し、その後Items.Clear()
を使用してそれらをすべて削除します。
そうでない場合は、おそらくインデクサーによって逆方向にループします。
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();
}
他の全員が「逆方向」の回答を投稿しているので、代わりに、削除するアイテムのリストを作成し、最後にそれらを削除します。
_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);
}
_
「backwards」メソッドの方が優れている場合もあれば、上記の方が優れている場合もあります-特にRemoveAll(collection)
メソッドを持つ型を扱う場合。しかし、両方を知っている価値があります。
ここに戻ると一時的なリストなしで私のソリューション
while (listBox1.Items.Count > 0)
{
string s = listBox1.Items[0] as string;
// do something with s
listBox1.Items.RemoveAt(0);
}
最後のアイテムから最初のアイテムまでコレクションを通過する必要があります。このコードはvbにあります
for i as integer= list.items.count-1 to 0 step -1
....
list.items.removeat(i)
next
ジェファーソンは正しい、あなたは逆方向にそれをしなければならない。
C#に相当するものは次のとおりです。
for (var i == list.Items.Count - 1; i >= 0; i--)
{
list.Items.RemoveAt(i);
}
while(listbox.Items.Remove(s)) ;
も動作するはずです。ただし、後方解決策は最速であると思います。
どうですか:
foreach(var s in listBox1.Items.ToArray())
{
MessageBox.Show(s);
//do stuff with (s);
listBox1.Items.Remove(s);
}
ToArrayはリストのコピーを作成するので、処理中にリストが変更されることを心配する必要はありません。
ForEachブロック内で反復されているコレクションを変更することはできません。
簡単な修正方法は、コレクションのコピーを反復処理することです。このコピーを作成する簡単な方法は、ArrayListコンストラクターを使用することです。コピーされたコレクション内のDataRowViewオブジェクトは、コードと同じ基礎データを参照し、変更できます。
For Each item As DataRowView In New System.Collections.ArrayList(lbOrdersNeedToBeVoided.Items)
お読みください http://social.msdn.Microsoft.com/Forums/en-AU/vbgeneral/thread/b4d1f649-d78a-4e5b-8ad8-1940e3379bed