?
Как использовать свойство CheckBoxes в ListView, что бы можно было пометить галочкой только одну строку, по аналогии с радио кнопкамиЭтот материал появился, когда мне никак не удавалось выбрать только одну строку, что бы затем, по нажатию кнопки выполнить действия только с одной строкой. Свойство "MultiSelect", установленное в значение равное "false" - не помогало, так как при нажатии кнопки, а дальнейшие действия планировалось выполнить именно по нажатию кнопки, селект со строки сбрасывался. Решение пришло не из интернета, так как там я его не нашел. Пришлось выкручиваться самому. Итак: На форме есть контрол "ListView", его мы инициализируем следующим образом: lv1.Items.Clear(); lv1.Columns.Clear(); lv1.ForeColor = Color.FromArgb(0, 0, 192); lv1.Font = button2.Font; lv1.MultiSelect = false; lv1.CheckBoxes = true; lv1.View = View.Details; lv1.GridLines = true; lv1.FullRowSelect = true; lv1.Columns.Add("ID записи", lv1.Width / 10, HorizontalAlignment.Left); lv1.Columns.Add("ID объекта", lv1.Width / 10, HorizontalAlignment.Left); lv1.Columns.Add("Объект", 2 * lv1.Width / 5, HorizontalAlignment.Left); lv1.Columns.Add("Дата", lv1.Width / 10, HorizontalAlignment.Left); lv1.Columns.Add("Описание", lv1.Width / 10, HorizontalAlignment.Left); Далее я простым селектом получил данные в DataRow[] (Об этом уже нам известно из раздела 5 книги: Работа с базами данных в Visual Studio .NET).
foreach (DataRow dr in drs) { s = dr["nameobj"].ToString().ToUpper(); string[] row = new string[5]; s = dr["datep"].ToString(); if (!string.IsNullOrEmpty(s)) { s = DateTime.Parse(s).ToString("dd.MM.yyyy"); } else { continue; } row[3] = s; s = dr["id"].ToString(); if (string.IsNullOrEmpty(s)) s = "0"; row[0] = s; row[1] = dr["idpoint"].ToString(); row[2] = dr["nameobj"].ToString(); s = dr["note"].ToString(); if (string.IsNullOrEmpty(s)) s = "0"; row[4] = s.Replace(",", "."); var listViewItem = new ListViewItem(row); lv1.Items.Add(listViewItem); } Обратим внимание на два свойства, первое из которых обязательно для многих операций, а второе позволяет отобразить чекбоксы перед каждой строкой: lv1.View = View.Details; lv1.CheckBoxes = true; С этого момента мы можем ставить галочки и сколько угодно, хоть у каждой строки, но нам нужна строка помеченная только одна. Для этого воспользуемся событием ListView - ItemCheck: private bool fL=false; private void lv1_ItemCheck(object sender, ItemCheckEventArgs e) { if (fL) return; //Эта блокировка необходима, что бы программа при смене выделенной строки не реагировала на //сброс галочки в ранее помеченной fL = true; //Запоминаем строку, в которой поставили галлочку int a = e.Index; //Сбрасываем все галочки for (int i = 0; i < lv1.Items.Count; i++) { lv1.Items[i].Checked = false; } //Восстанавливаем галочку в последней выделенной строке lv1.Items[a].Checked = true; //С этого момента у меня помечена галочкой только одна строка, при попытке поставить галочку против //другой строки, ранее установленная галочка сбрасывается. //С этого момента я могу делать со строкой все, что хочу //Например, выделяю ее и помещаю содержимое в отделные TextBox (это к пометке галочками строк не относится, //но служит как пример для чтения данных из ListView) lv1.Items[a].Selected = true; if (lv1.SelectedItems.Count > 0) { tbId.Text = lv1.SelectedItems[0].Text; tbIdO.Text = lv1.SelectedItems[0].SubItems[1].Text; tbO.Text = lv1.SelectedItems[0].SubItems[2].Text; tbP.Text = lv1.SelectedItems[0].SubItems[4].Text.Replace(",", "."); } fL = false; } Теперь нам не важно, что при нажатии кнопки на форме пропадет селект на выделенной строке - мы можем работать со строкой, используя свойство "CheckedItems" - у нас одна выделенная строка и мы можем быть в этом уверены! private void button5_Click(object sender, EventArgs e) { if (lv1.Items.Count <= 0) return; if (lv1.CheckedItems.Count != 1) { s = "Не помечена галочкой строка, которую Вы хотите изменить!"; MessageBox.Show(s, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } ..... Молчанов Владислав 27.11.2013г. |