Verwenden eines ComboBox-Steuerelements zum Bearbeiten von Daten in einem ListView-Steuerelement in Visual CSharp

In diesem Artikel wird veranschaulicht, wie Sie ein ComboBox-Steuerelement verwenden, um die Daten in einem ListView-Steuerelement zu bearbeiten. Diese Methode ersetzt den Standard-Textfeldansatz zum Bearbeiten der Daten in einem ListView-Steuerelement.

Ursprüngliche Produktversion: Visual C#
Ursprüngliche KB-Nummer: 320344

Beschreibung der Technik

Mithilfe der LabelEdit -Eigenschaft des ListView-Steuerelements können Sie dem Benutzer erlauben, den Inhalt des ListView-Steuerelements zu bearbeiten. Zum Bearbeiten der Daten im ListView-Steuerelement können Sie ein Standardtextfeld verwenden. Gelegentlich ist es nützlich, ein anderes Steuerelement zum Bearbeiten des Steuerelements zu verwenden. In diesem Artikel wird die Verwendung eines ComboBox-Steuerelements zum Bearbeiten der Daten in einer ListView simuliert, wenn sich die ListView in der Detailansicht befindet.

Wenn der Benutzer eine Zeile in der ListView auswählt, wird eine Berechnung durchgeführt, um das umgebende Rechteck für die erste Spalte der Zeile zu suchen, auf die geklickt wird. Bei dieser Berechnung wird berücksichtigt, dass die Spalte möglicherweise nicht oder nicht vollständig sichtbar ist, wenn auf die Zeile geklickt wird und die Größe des ComboBox-Steuerelements entsprechend angepasst und angezeigt wird.

Zusätzlich zur Positionierung und Größenanpassung des ComboBox-Steuerelements wird in diesem Beispiel auch auf zwei Nachrichten im ListView-Steuerelement überwacht: WM_VSCROLL und WM_HSCROLL. Diese Meldungen treten auf, wenn der Benutzer vertikal oder horizontal durch das ListView-Steuerelement scrollt. Da das ComboBox-Steuerelement nicht physisch Teil des ListView-Steuerelements ist, führt das ComboBox-Steuerelement nicht automatisch einen Bildlauf mit der ListView durch. Wenn also eine dieser beiden Meldungen auftritt, muss das ComboBox-Objekt ausgeblendet werden. Um watch für diese Nachrichten zu erstellen, erstellen Sie eine benutzerdefinierte UserControl Klasse, die von der ListView-Klasse erbt. In diesem benutzerdefinierten Steuerelement wird die WndProc -Methode überschrieben, damit alle Nachrichten auf Bildlauf überprüft werden können.

Erstellen des geerbten ListView-Steuerelements

  1. Starten Sie Microsoft Visual Studio .NET.

  2. Zeigen Sie im Menü Datei auf Neu, und klicken Sie dann auf Projekt.

  3. Klicken Sie im Dialogfeld Neues Projekt unter Projekttypen auf Visual C#-Projekte, und klicken Sie dann unter Vorlagen auf Windows-Steuerelementbibliothek.

  4. Ersetzen Sie den gesamten Code in der UserControl -Klasse durch den folgenden Code:

    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. Speichern und erstellen Sie das Projekt.

Erstellen der Beispielanwendung

  1. Führen Sie die folgenden Schritte aus, um eine neue Windows-Anwendung in Visual C# .NET zu erstellen:

    1. Zeigen Sie im Menü Datei auf Neu, und klicken Sie dann auf Projekt.
    2. Klicken Sie im Dialogfeld Neues Projekt unter Projekttypen auf Visual C#-Projekte, und klicken Sie dann unter Vorlagen auf Windows-Anwendung. Standardmäßig wird Form1 erstellt.
  2. Führen Sie die folgenden Schritte aus, um das Steuerelement, das Sie im Abschnitt Erstellen des geerbten ListView-Steuerelements erstellt haben, ihrer Windows-Anwendung hinzuzufügen:

    1. Klicken Sie im Menü Extras auf Toolbox anpassen.
    2. Klicken Sie auf der Registerkarte .NET Framework Komponenten auf Durchsuchen.
    3. Suchen Sie im Dialogfeld Öffnen das Steuerelement, das Sie im Abschnitt Erstellen des geerbten ListView-Steuerelements erstellt haben, und klicken Sie dann auf Öffnen. Es fügt dieses Steuerelement der Toolbox hinzu, sodass Sie das Steuerelement ähnlich wie jedes andere Steuerelement verwenden können.
    4. Ziehen Sie MyListView aus dem Abschnitt Allgemein der Toolbox in Form1.
  3. Ziehen Sie ein ComboBox-Steuerelement aus dem Windows Forms Abschnitt der Toolbox auf Form1.

  4. Ändern Sie im Eigenschaftenfenster von ComboBox die Name-Eigenschaft in cbListViewCombo, und legen Sie dann die Visible-Eigenschaft auf False fest.

  5. Fügen Sie der Klasse von oberhalb des Form1 Konstruktors den folgenden Code hinzu:

    private ListViewItem lvItem;
    
  6. Fügen Sie dem Ereignis von Form1 den Load folgenden Code hinzu:

    // 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. Fügen Sie dem -Ereignis des ComboBox-Objekts den SelectedValueChanged folgenden Code hinzu:

    // Set text of ListView item to match the ComboBox.
    lvItem.Text = this.cbListViewCombo.Text;
    
    // Hide the ComboBox.
    this.cbListViewCombo.Visible = false;
    
  8. Fügen Sie dem -Ereignis des ComboBox-Objekts den Leave folgenden Code hinzu:

    // Set text of ListView item to match the ComboBox.
    lvItem.Text = this.cbListViewCombo.Text;
    
    // Hide the ComboBox.
    this.cbListViewCombo.Visible = false;
    
  9. Fügen Sie dem -Ereignis des ComboBox-Objekts den KeyPress folgenden Code hinzu:

    // 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. Fügen Sie dem Ereignis von myListView1den MouseUp folgenden Code hinzu:

    // 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();
    }
    

Überprüfen, ob es funktioniert

  1. Speichern Sie das Beispiel, und führen Sie es aus.

  2. Klicken Sie in listView auf eine Zeile.

    Hinweis

    Über der Position der ersten Spalte der aktuellen Zeile wird ein Kombinationsfeld angezeigt.

  3. Klicken Sie zum Ausblenden des Kombinationsfelds auf ein Element im Kombinationsfeld, drücken Sie ESC, und scrollen Sie dann durch listView, oder klicken Sie auf ein anderes Steuerelement.

    Hinweis

    Der Wert, auf den Sie im Kombinationsfeld geklickt haben, wird in der ersten Spalte der Zeile listView platziert, auf die geklickt wurde.