Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
W tym artykule pokazano, jak używać kontrolki ComboBox do edytowania danych w kontrolce ListView. Ta metoda zastępuje standardowe podejście pola tekstowego do edytowania danych w kontrolce ListView.
Oryginalna wersja produktu: Visual C#
Oryginalny numer KB: 320344
Opis techniki
Za pomocą LabelEdit
właściwości kontrolki ListView możesz zezwolić użytkownikowi na edytowanie zawartości kontrolki ListView. Aby edytować dane w kontrolce ListView, możesz użyć standardowego pola tekstowego. Czasami warto mieć inną kontrolkę do edycji kontrolki. W tym artykule symuluje się, jak używać kontrolki ComboBox do edytowania danych w kontrolce ListView, gdy element ListView jest w widoku Szczegóły.
Gdy użytkownik wybierze wiersz w widoku ListView, obliczenie jest wykonywane w celu zlokalizowania prostokąta ograniczenia dla pierwszej kolumny wiersza, który jest kliknięty. To obliczenie uwzględnia, że kolumna może nie być widoczna lub może nie być w pełni widoczna po kliknięciu wiersza i odpowiednim rozmiarze kombiBox.
Oprócz pozycjonowania i określania rozmiaru pola ComboBox w tym przykładzie są również wyświetlane dwa komunikaty w kontrolce ListView: WM_VSCROLL
i WM_HSCROLL
. Te komunikaty są wykonywane za każdym razem, gdy użytkownik przewija kontrolkę ListView w pionie lub w poziomie. Ponieważ pole ComboBox nie jest fizycznie częścią kontrolki ListView, pole ComboBox nie przewija się automatycznie za pomocą kontrolki ListView. Dlatego za każdym razem, gdy wystąpi jeden z tych dwóch komunikatów, pole ComboBox musi być ukryte. Aby obserwować te komunikaty, należy utworzyć klasę niestandardową UserControl
dziedziczą z klasy ListView. W tej kontrolce niestandardowej WndProc
metoda jest zastępowana, aby umożliwić sprawdzanie wszystkich komunikatów pod kątem przewijania.
Tworzenie dziedziczonej kontrolki ListView
Uruchom program Microsoft Visual Studio .NET.
W menu Plik wskaż polecenie Nowy, a następnie kliknij Projekt.
W oknie dialogowym Nowy projekt kliknij pozycję Projekty Visual C# w obszarze Typy projektów, a następnie kliknij pozycję Biblioteka kontrolek systemu Windows w obszarze Szablony.
Zastąp cały kod w
UserControl
klasie następującym kodem: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); } } }
Zapisz i skompiluj projekt.
Tworzenie przykładowej aplikacji
Wykonaj następujące kroki, aby utworzyć nową aplikację systemu Windows na platformie .NET języka Visual C#:
- W menu Plik wskaż polecenie Nowy, a następnie kliknij Projekt.
- W oknie dialogowym Nowy projekt kliknij pozycję Projekty Visual C# w obszarze Typy projektów, a następnie kliknij pozycję Aplikacja systemu Windows w obszarze Szablony. Domyślnie formularz Form1 jest tworzony.
Wykonaj następujące kroki, aby dodać kontrolkę utworzoną w sekcji Tworzenie dziedziczonej kontrolki ListView do aplikacji systemu Windows:
- W menu Narzędzia kliknij pozycję Dostosuj przybornik.
- Na karcie Składniki programu .NET Framework kliknij przycisk Przeglądaj.
- W oknie dialogowym Otwieranie znajdź kontrolkę utworzoną w sekcji Tworzenie dziedziczonej kontrolki ListView, a następnie kliknij przycisk Otwórz. Dodaje tę kontrolkę do przybornika, aby można było użyć kontrolki podobnie jak w przypadku każdej innej kontrolki.
- Przeciągnij element MyListView z sekcji Ogólne przybornika do formularza Form1.
Przeciągnij kontrolkę ComboBox z sekcji Formularze systemu Windows przybornika do formularza Form1.
W oknie Właściwości pola ComboBox zmień właściwość Name na cbListViewCombo, a następnie ustaw właściwość Visible na False.
Dodaj następujący kod do klasy
Form1
powyżej konstruktora:private ListViewItem lvItem;
Dodaj następujący kod do
Load
zdarzenia 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; }
Dodaj następujący kod do
SelectedValueChanged
zdarzenia ComboBox:// Set text of ListView item to match the ComboBox. lvItem.Text = this.cbListViewCombo.Text; // Hide the ComboBox. this.cbListViewCombo.Visible = false;
Dodaj następujący kod do
Leave
zdarzenia ComboBox:// Set text of ListView item to match the ComboBox. lvItem.Text = this.cbListViewCombo.Text; // Hide the ComboBox. this.cbListViewCombo.Visible = false;
Dodaj następujący kod do
KeyPress
zdarzenia 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; } }
Dodaj następujący kod do
MouseUp
zdarzenia :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(); }
Sprawdź, czy działa
Zapisz i uruchom przykład.
Kliknij wiersz w widoku ListView.
Uwaga 16.
Pole kombi pojawia się nad lokalizacją pierwszej kolumny bieżącego wiersza.
Aby ukryć pole kombi, kliknij element w polu kombi, naciśnij ESC, a następnie przewiń widok ListView lub kliknij inną kontrolkę.
Uwaga 16.
Wartość klikniętą w polu kombi znajduje się w pierwszej kolumnie klikniętego wiersza elementu ListView.