Работаем с ListView в коде
Заполняем ListView во время работы проекта. Большинство приложений Windows позволяют менять содержимое списка ListView во время работы проекта. Так, Проводник Windows при переходе из папки в папку меняет содержимое своей правой панели. В принципе, вы скоро сможете частично воспроизвести работу Проводника Windows.
Вы будете иметь возможность вручную во время работы проекта редактировать (менять) текст в первом столбце списка, если предварительно установите в True свойство LabelEdit списка ListView. Обратившись к элементам коллекций SubItems в коде, вы сможете делать то же самое и с другими столбцами (хотя бы при помощи InputBox).
Часто бывает необходимо предоставить пользователю возможность заполнять список ListView из файла и сохранять его в файле. Сейчас мы и рассмотрим этот способ заполнения и сохранения.
В Задание 136 от вас требовалось заполнять из текстового файла и сохранять в текстовый файле массив структур. Если вы не выполнили это задание, то загляните в ответ и разберитесь в программе. Отличие нашего случая в том, что вместо массива структур у нас – коллекции списка. Рассмотрим сначала сохранение.
Сохраняем ListView в файл. Забудем для простоты о флажках и картинках. Пусть информация в текстовом файле должна быть расположена в такой последовательности:
StarDraft
300
нет
UntiReal
500
да
Suake
200
нет
Feroes III
800
да
Ниже я привожу 5 процедур, соответствующих 5 кнопкам проекта на Рис. 20.11. Вот процедура, сохраняющая список LV в файл:
Dim i As Integer 'Счетчик игр
Private Sub Сохранить(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Сохранить.Click
Dim Запись As New System.IO.StreamWriter("E:\VB\Игры.txt")
For i = 0 To LV.Items.Count
- 1
Запись.WriteLine(LV.Items(i).SubItems(0).Text) 'Запись 1 столбца i-й строки
Запись.WriteLine(LV.Items(i).SubItems(1).Text) 'Запись 2 столбца i-й строки
Запись.WriteLine(LV.Items(i).SubItems(2).Text) 'Запись 3 столбца i-й строки
Next
Запись.Close()
End Sub
Пояснения: Поскольку составные части информации в списке ListView представляют собой элементы той или иной коллекции, а работу с коллекциями мы изучали в 16.2, программирование не должно натолкнуться на непреодолимые препятствия. Разве что на отсутствие привычки. Коллекция Items имеет свойство Count, которое показывает количество элементов в коллекции, то есть количество строк в списке. Первый элемент имеет номер 0, последний – LV.Items.Count-1. Переменную i я сделал модульной, так как не хотелось объявлять ее в каждой процедуре. Но это грех.
Заполняем ListView из файла. Пусть в проекте уже существует список LV. Он может быть заполнен информацией или совсем не заполнен (как на Рис. 20.13). Нам нужно его заново заполнить из файла. Вот процедура:
Private Sub Загрузить(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Загрузить.Click
'Очищаем список:
Do Until LV.Items.Count = 0 'Удаляй по элементу, пока элементов не останется
LV.Items(0).Remove() 'Индекс 0 потому, что при удалении элементы списка сдвигаются вверх
Loop
'Загружаем список:
Dim Чтение As New System.IO.StreamReader("E:\VB\Игры.txt")
i = 0
Do While Чтение.Peek() <> -1
'Добавляем в список очередную строку и одновременно заполняем ее первый столбец:
LV.Items.Add(Чтение.ReadLine)
LV.Items(i).SubItems.Add(Чтение.ReadLine) 'Заполняем второй столбец очередной строки
LV.Items(i).SubItems.Add(Чтение.ReadLine) 'Заполняем третий столбец очередной строки
i = i + 1
Loop
Чтение.Close()
End Sub
Пояснения: Оператор LV.Items(0).Remove() удаляет каждый раз верхнюю строку списка, а остальные строки тут же сдвигаются наверх. Не путайте метод Items.Add, который добавляет элемент в коллекцию Items, и метод SubItems.Add, который добавляет элемент в коллекцию SubItems.
Работаем со списком ListView. В качестве примера работы со списком ListView я выбрал добавление игр в список, удаление игр из списка и исправление строк списка. Список ListView поддерживает множественный выбор и я это учел. Если вы выделили одну строку, то удаляется и исправляется только эта одна строка, если же вы выделили несколько строк, то удаляются и исправляются сразу все выделенные строки. Чтобы множественный выбор был возможен, нужно установить в True свойство MultiSelect.
Добавление:
Private Sub Добавить(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Добавить.Click
'Добавляем в список строку и одновременно заполняем ее первый столбец:
LV.Items.Add(InputBox("Введите название игры"))
'Добавляем в строку еще два элемента:
LV.Items(LV.Items.Count - 1).SubItems.Add(InputBox("Введите объем игры в мегабайтах"))
LV.Items(LV.Items.Count - 1).SubItems.Add(InputBox("Оцените качество графики (да-нет)"))
End Sub
Пояснения: Номер LV.Items.Count-1 имеет как раз только что добавленная в список строка.
Удаление:
Private Sub Удаление(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Удаление.Click
For i = LV.Items.Count - 1 To 0 Step -1
If LV.SelectedIndices.Contains(i) Then
LV.Items(i).Remove()
End If
Next
End Sub
Пояснения: В списке ListView имеются коллекции SelectedItems и SelectedIndices. Они состоят из выбранных элементов и их номеров соответственно. В коллекции SelectedIndices имеется метод Contains, который определяет, входит ли некоторый номер элемента списка ListView (в нашем случае i) в эту коллекцию. Поэтому оператор
If LV.SelectedIndices.Contains(i) Then
можно перевести так: «Если среди номеров выбранных элементов списка встречается число i, то …».
Обратите внимание, что цикл по строкам идет не сверху вниз, а снизу вверх. Я был вынужден это сделать, так как в процессе удаления нескольких строк получается, что после удаления очередной строки все нижние строки сдвигаются вверх, а значит следующей строкой удаляется не та, что нужно, а нижележащая.
Исправление:
Private Sub Исправить(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Исправить.Click
Dim Название As String = InputBox("Введите название игры")
Dim Объем As String = InputBox("Введите объем игры в мегабайтах")
Dim Графика As String = InputBox("Оцените качество графики (да-нет)")
For i = 0 To LV.Items.Count - 1
If LV.SelectedIndices.Contains(i) Then
LV.Items(i).SubItems(0).Text = Название
LV.Items(i).SubItems(1).Text = Объем
LV.Items(i).SubItems(2).Text = Графика
End If
Next
End Sub
Пояснения: После исправления все выделенные строки становятся одинаковыми.