Использование элемента управления ComboBox для изменения данных в элементе управления ListView в Visual CSharp
В этой статье показано, как использовать элемент управления ComboBox для редактирования данных в элементе управления ListView. Этот метод заменяет стандартный подход к текстовым полям для редактирования данных в элементе управления ListView.
Исходная версия продукта: Visual C#
Исходный номер базы знаний: 320344
Описание метода
С помощью LabelEdit
свойства элемента управления ListView можно разрешить пользователю изменять содержимое элемента управления ListView. Чтобы изменить данные в элементе управления ListView, можно использовать стандартное текстовое поле. Иногда полезно использовать другой элемент управления для редактирования элемента управления. В этой статье имитируется использование элемента управления ComboBox для редактирования данных в ListView, когда ListView находится в представлении Сведений.
Когда пользователь выбирает строку в ListView, выполняется вычисление, чтобы найти ограничивающий прямоугольник для первого столбца в строке, которую щелкают. Это вычисление учитывает, что столбец может быть невидимым или не полностью видимым при щелчке строки и при соответствующем размере и отображении элемента ComboBox.
Помимо позиционирования и изменения размера ComboBox, этот пример также следит за двумя сообщениями в элементе управления ListView: WM_VSCROLL
и WM_HSCROLL
. Эти сообщения возникают всякий раз, когда пользователь прокручивает элемент управления ListView по вертикали или по горизонтали. Так как comboBox физически не является частью элемента управления ListView, comboBox не прокручивается автоматически с помощью ListView. Поэтому при возникновении любого из этих двух сообщений поле ComboBox должно быть скрыто. Чтобы watch для этих сообщений, создайте пользовательский UserControl
класс, наследующий от класса ListView. В этом пользовательском элементе WndProc
управления метод переопределяется, чтобы разрешить проверку прокрутки всех сообщений.
Создание унаследованного элемента управления ListView
Запустите Microsoft Visual Studio .NET.
В меню Файл выберите пункт Создать и затем пункт Проект.
В диалоговом окне Новый проект выберите Пункт Проекты Visual C# в разделе Типы проектов, а затем выберите Библиотека элементов управления Windows в разделе Шаблоны.
Замените весь код в
UserControl
классе следующим кодом:using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Data; using System.Windows.Forms; namespace InheritedListView { /// <summary> /// Summary description for UserControl1. /// </summary> public class MyListView : System.Windows.Forms.ListView { /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.Container components = null; public MyListView() { // This call is required by the Windows.Forms Form Designer. InitializeComponent(); // TODO: Add any initialization after the InitForm call } /// <summary> /// Clean up any resources being used. /// </summary> protected override void Dispose(bool disposing) { if (disposing) { if (components != null) components.Dispose(); } base.Dispose(disposing); } #region Component Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { components = new System.ComponentModel.Container(); } #endregion private const int WM_HSCROLL = 0x114; private const int WM_VSCROLL = 0x115; protected override void WndProc(ref Message msg) { // Look for the WM_VSCROLL or the WM_HSCROLL messages. if ((msg.Msg == WM_VSCROLL) || (msg.Msg == WM_HSCROLL)) { // Move focus to the ListView to cause ComboBox to lose focus. this.Focus(); } // Pass message to default handler. base.WndProc(ref msg); } } }
Сохраните изменения и выполните построение проекта.
Создание примера приложения
Чтобы создать новое приложение Windows в Visual C# .NET, выполните следующие действия:
- В меню Файл выберите пункт Создать и затем пункт Проект.
- В диалоговом окне Новый проект щелкните Проекты Visual C# в разделе Типы проектов, а затем выберите Приложение Windows в разделе Шаблоны. По умолчанию создается Form1.
Чтобы добавить элемент управления, созданный в разделе Создание унаследованного элемента управления ListView , в приложение Windows выполните следующие действия.
- В меню Сервис выберите пункт Настроить панель элементов.
- На вкладке компоненты платформа .NET Framework нажмите кнопку Обзор.
- В диалоговом окне Открыть найдите элемент управления, созданный в разделе Создание унаследованного элемента управления ListView , и нажмите кнопку Открыть. Он добавляет этот элемент управления на панель элементов, чтобы его можно было использовать аналогично любому другому элементу управления.
- Перетащите MyListView из раздела Общие панели элементов в Form1.
Перетащите элемент управления ComboBox из раздела Windows Forms панели элементов в Form1.
В окне Свойства comboBox измените свойство Name на cbListViewCombo, а затем задайте для свойства Visible значение False.
Добавьте следующий код в класс
Form1
над конструктором:private ListViewItem lvItem;
Добавьте следующий код в
Load
событие Form1:// Add a few items to the combo box list. this.cbListViewCombo.Items.Add("NC"); this.cbListViewCombo.Items.Add("WA"); // Set view of ListView to Details. this.myListView1.View = View.Details; // Turn on full row select. this.myListView1.FullRowSelect = true; // Add data to the ListView. ColumnHeader columnheader; ListViewItem listviewitem; // Create sample ListView data. listviewitem = new ListViewItem("NC"); listviewitem.SubItems.Add("North Carolina"); this.myListView1.Items.Add(listviewitem); listviewitem = new ListViewItem("WA"); listviewitem.SubItems.Add("Washington"); this.myListView1.Items.Add(listviewitem); // Create column headers for the data. columnheader = new ColumnHeader(); columnheader.Text = "State Abbr."; this.myListView1.Columns.Add(columnheader); columnheader = new ColumnHeader(); columnheader.Text = "State"; this.myListView1.Columns.Add(columnheader); // Loop through and size each column header to fit the column header text. foreach (ColumnHeader ch in this.myListView1.Columns) { ch.Width = -2; }
Добавьте следующий код в
SelectedValueChanged
событие ComboBox:// Set text of ListView item to match the ComboBox. lvItem.Text = this.cbListViewCombo.Text; // Hide the ComboBox. this.cbListViewCombo.Visible = false;
Добавьте следующий код в
Leave
событие ComboBox:// Set text of ListView item to match the ComboBox. lvItem.Text = this.cbListViewCombo.Text; // Hide the ComboBox. this.cbListViewCombo.Visible = false;
Добавьте следующий код в
KeyPress
событие ComboBox:// Verify that the user presses ESC. switch (e.KeyChar) { case (char)(int)Keys.Escape: { // Reset the original text value, and then hide the ComboBox. this.cbListViewCombo.Text = lvItem.Text; this.cbListViewCombo.Visible = false; break; } case (char)(int)Keys.Enter: { // Hide the ComboBox. this.cbListViewCombo.Visible = false; break; } }
Добавьте следующий код в
MouseUp
событиеmyListView1
:// Get the item on the row that is clicked. lvItem = this.myListView1.GetItemAt(e.X, e.Y); // Make sure that an item is clicked. if (lvItem != null) { // Get the bounds of the item that is clicked. Rectangle ClickedItem = lvItem.Bounds; // Verify that the column is completely scrolled off to the left. if ((ClickedItem.Left + this.myListView1.Columns[0].Width) < 0) { // If the cell is out of view to the left, do nothing. return; } // Verify that the column is partially scrolled off to the left. else if (ClickedItem.Left < 0) { // Determine if column extends beyond right side of ListView. if ((ClickedItem.Left + this.myListView1.Columns[0].Width) > this.myListView1.Width) { // Set width of column to match width of ListView. ClickedItem.Width = this.myListView1.Width; ClickedItem.X = 0; } else { // Right side of cell is in view. ClickedItem.Width = this.myListView1.Columns[0].Width + ClickedItem.Left; ClickedItem.X = 2; } } else if (this.myListView1.Columns[0].Width > this.myListView1.Width) { ClickedItem.Width = this.myListView1.Width; } else { ClickedItem.Width = this.myListView1.Columns[0].Width; ClickedItem.X = 2; } // Adjust the top to account for the location of the ListView. ClickedItem.Y += this.myListView1.Top; ClickedItem.X += this.myListView1.Left; // Assign calculated bounds to the ComboBox. this.cbListViewCombo.Bounds = ClickedItem; // Set default text for ComboBox to match the item that is clicked. this.cbListViewCombo.Text = lvItem.Text; // Display the ComboBox, and make sure that it is on top with focus. this.cbListViewCombo.Visible = true; this.cbListViewCombo.BringToFront(); this.cbListViewCombo.Focus(); }
Убедитесь, что он работает
Сохраните и запустите пример.
Щелкните строку в ListView.
Примечание.
Над расположением первого столбца текущей строки появится поле со списком.
Чтобы скрыть поле со списком, щелкните элемент в поле со списком, нажмите клавишу ESC, а затем прокрутите listView или щелкните другой элемент управления.
Примечание.
Значение, выбранное в поле со списком, помещается в первый столбец щелкнутой строки ListView.
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по