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

In diesem Artikel wird die Verwendung eines ComboBox-Steuerelements zum Bearbeiten der Daten in einem ListView-Steuerelement veranschaulicht. Diese Methode ersetzt den Standardmäßigen Textfeldansatz zum Bearbeiten der Daten in einem ListView-Steuerelement.

Originalversion des Produkts:   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 hilfreich, 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 listView in der Detailansicht befindet.

Wenn der Benutzer eine Zeile in der ListView auswählt, wird eine Berechnung durchgeführt, um das Begrenzungsrechteck 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 sichtbar oder nicht vollständig sichtbar ist, wenn auf die Zeile geklickt wird und die Größe des ComboBox-Steuerelements entsprechend angepasst und angezeigt wird.

Neben der Positionierung und Größenanpassung des ComboBox-Steuerelements werden in diesem Beispiel auch zwei Nachrichten im ListView-Steuerelement überwacht: WM_VSCROLL und WM_HSCROLL. Diese Meldungen treten immer dann 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 listView durch. Jedes Mal, wenn eine dieser beiden Meldungen auftritt, muss das ComboBox-Steuerelement ausgeblendet werden. Um diese Nachrichten zu überwachen, erstellen Sie eine benutzerdefinierte UserControl Klasse, die von der ListView-Klasse erbt. In diesem benutzerdefinierten Steuerelement wird die WndProc Methode überschrieben, damit alle Nachrichten für den 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 "Neuer Project" unter Project Typen 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 "Neuer Project" unter Project Typen 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 nach Form1.
  3. Ziehen Sie ein ComboBox-Steuerelement aus dem Windows Forms Abschnitt der Toolbox nach 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 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 SelectedValueChanged Ereignis des ComboBox-Steuerelements den 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 Leave Ereignis des ComboBox-Steuerelements den 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 KeyPress Ereignis des ComboBox-Steuerelements den 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 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();
    }
    

Überprüfen, ob es funktioniert

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

  2. Klicken Sie in der ListView auf eine Zeile.

    Hinweis

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

  3. Um das Kombinationsfeld auszublenden, klicken Sie auf ein Element im Kombinationsfeld, drücken Sie ESC, und scrollen Sie dann durch die ListView, oder klicken Sie auf ein anderes Steuerelement.

    Hinweis

    Der Wert, auf den Sie im Kombinationsfeld geklickt haben, wird in der ersten Spalte der angeklickten Zeile des ListView-Steuerelements platziert.