Прослеживание через список и доступ к подпунктам?
Мне сложно использовать инструкцию foreach с помощью элемента управления ListView WinForm. Следующие два блока кода демонстрируют то, что я пытаюсь сделать. Он работает с циклом 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
}
Я пытаюсь использовать цикл foreach, чтобы я мог легче удалить элементы из ListView.
Ответы
Ответ 1
Вам нужно указать тип:
foreach(ListViewItem item in listView.Items){
Чтобы ответить на ваши комментарии:
Это связано с тем, что большинство коллекций элементов управления реализуют не общие ICollection
(и IEnumerable
), см. эту запись MSDN для ListViewItemCollection
например. Так как он не реализует общие ICollection<T>
или IEnumerable<T>
, компилятор не может угадать тип элементов от просмотра самих коллекций, поэтому вам нужно сказать, что они имеют тип ListViewItem
вместо этого использования var
.
Ответ 2
Вам нужно указать тип, если элемент в коллекции явно. Ключевое слово 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
.
Ответ 3
Вам нужно иметь тип элемента - в этом случае: ListViewItem
.
Кроме того, если вы планируете удалить элементы из коллекции и используете цикл foreach, вы не можете напрямую удалить из цикла, то вам нужно будет добавить каждый элемент для удаления в новую коллекцию и удалите все элементы в этой коллекции из оригинала после окончания цикла.
Ответ 4
Используйте красивую коллекцию литейщиков LINQ
using System.Linq;
foreach(var item in listView.Items.Cast<ListViewItem>()){
item.BackColor = ...
}