Udostępnij za pośrednictwem


Edytowanie danych w kontrolce ListView w visual CSharp za pomocą kontrolki ComboBox

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

  1. Uruchom program Microsoft Visual Studio .NET.

  2. W menu Plik wskaż polecenie Nowy, a następnie kliknij Projekt.

  3. 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.

  4. 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);
            }
        }
    }
    
  5. Zapisz i skompiluj projekt.

Tworzenie przykładowej aplikacji

  1. Wykonaj następujące kroki, aby utworzyć nową aplikację systemu Windows na platformie .NET języka Visual C#:

    1. W menu Plik wskaż polecenie Nowy, a następnie kliknij Projekt.
    2. 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.
  2. Wykonaj następujące kroki, aby dodać kontrolkę utworzoną w sekcji Tworzenie dziedziczonej kontrolki ListView do aplikacji systemu Windows:

    1. W menu Narzędzia kliknij pozycję Dostosuj przybornik.
    2. Na karcie Składniki programu .NET Framework kliknij przycisk Przeglądaj.
    3. 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.
    4. Przeciągnij element MyListView z sekcji Ogólne przybornika do formularza Form1.
  3. Przeciągnij kontrolkę ComboBox z sekcji Formularze systemu Windows przybornika do formularza Form1.

  4. 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.

  5. Dodaj następujący kod do klasy Form1 powyżej konstruktora:

    private ListViewItem lvItem;
    
  6. 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;
    }
    
  7. 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;
    
  8. 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;
    
  9. 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;
       }
    }
    
  10. 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

  1. Zapisz i uruchom przykład.

  2. Kliknij wiersz w widoku ListView.

    Uwaga 16.

    Pole kombi pojawia się nad lokalizacją pierwszej kolumny bieżącego wiersza.

  3. 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.