WinForm ListViewコントロールでforeachステートメントを使用するのに問題があります。次の2つのコードブロックは、私がやろうとしていることを示しています。これはforループでは機能しますが、foreachでは機能しません。
foreach(var item in listView.Items){
item. <-Can't access any of the subitems of this item
}
対
for(int i=0;i<listView.Items.Count;i++){
listView.Items[i].Subitems[1] <- Here I can access the sub items
}
ListViewから項目をより簡単に削除できるように、foreachループを使用しようとしています。
タイプを指定する必要があります:
foreach(ListViewItem item in listView.Items){
あなたのコメントに答えるには:
これは、ほとんどのコントロールのアイテムコレクションが非ジェネリックICollection
(およびIEnumerable
)を実装しているためです。たとえば、ListViewItemCollection
の- このMSDNエントリ を参照してください。汎用のICollection<T>
またはIEnumerable<T>
を実装していないため、コンパイラーはコレクション自体を見てアイテムのタイプを推測できないため、コレクションのタイプであることを通知する必要がありますListViewItem
を使用する代わりにvar
。
コレクション内のアイテムのタイプを明示的に指定する必要があります。 var
キーワードは、変数の型を判別するために型推論を使用します。 var
句のforeach
の場合は、IEnumerable
の特定の実装を使用してタイプを判別します。
IEnumerable
だけを実装している場合(ジェネリックIEnumerable<T>
ではない)、var
はobject
になります。IEnumerable<T>
(たとえば、IEnumerable<int>
)を実装する場合、var
はT
になります(この例では、var
はint
)あなたの場合、ListViewItemCollection
はIEnumerable<T>
の一般的な形式を実装していないため、var
はobject
であると見なされます。ただし、列挙型がIEnumerable
のみを実装し、その特定の型へのキャストを自動的に挿入する場合、コンパイラーはイテレーター変数のより具体的な型を指定できます。
キャスト演算子があるため、オブジェクトがその特定のタイプでない場合、実行時にキャストが失敗することに注意してください。たとえば、私はこれを行うことができます:
List<object> foo = new List<object>();
foo.Add("bar");
foo.Add(1);
foreach(string bar in foo)
{
}
これは正当ですが、string
ではないため、イテレータが2番目のアイテムに到達すると失敗します。
アイテムのタイプ(この場合はListViewItem
)が必要です。
また、コレクションからアイテムを削除する予定で、foreachループを使用している場合は、ループしているから直接削除することはできません。削除する各アイテムを新しいコレクションに追加して、すべてのアイテムを削除する必要があります。ループの終了後、元のコレクションから。
LINQの美しいコレクションキャスターを使用する
using System.Linq;
foreach(var item in listView.Items.Cast<ListViewItem>()){
item.BackColor = ...
}