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
Starten Sie Microsoft Visual Studio .NET.
Zeigen Sie im Menü Datei auf Neu, und klicken Sie dann auf Projekt.
Klicken Sie im Dialogfeld Neues Projekt unter Projekttypen auf Visual C#-Projekte, und klicken Sie dann unter Vorlagen auf Windows-Steuerelementbibliothek.
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); } } }
Speichern und erstellen Sie das Projekt.
Erstellen der Beispielanwendung
Führen Sie die folgenden Schritte aus, um eine neue Windows-Anwendung in Visual C# .NET zu erstellen:
- Zeigen Sie im Menü Datei auf Neu, und klicken Sie dann auf Projekt.
- 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.
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:
- Klicken Sie im Menü Extras auf Toolbox anpassen.
- Klicken Sie auf der Registerkarte .NET Framework Komponenten auf Durchsuchen.
- 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.
- Ziehen Sie MyListView aus dem Abschnitt Allgemein der Toolbox in Form1.
Ziehen Sie ein ComboBox-Steuerelement aus dem Windows Forms Abschnitt der Toolbox auf Form1.
Ändern Sie im Eigenschaftenfenster von ComboBox die Name-Eigenschaft in cbListViewCombo, und legen Sie dann die Visible-Eigenschaft auf False fest.
Fügen Sie der Klasse von oberhalb des
Form1
Konstruktors den folgenden Code hinzu:private ListViewItem lvItem;
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; }
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;
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;
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; } }
Fügen Sie dem Ereignis von
myListView1
denMouseUp
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
Speichern Sie das Beispiel, und führen Sie es aus.
Klicken Sie in listView auf eine Zeile.
Hinweis
Über der Position der ersten Spalte der aktuellen Zeile wird ein Kombinationsfeld angezeigt.
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.
Feedback
https://aka.ms/ContentUserFeedback.
Bald verfügbar: Im Laufe des Jahres 2024 werden wir GitHub-Issues stufenweise als Feedbackmechanismus für Inhalte abbauen und durch ein neues Feedbacksystem ersetzen. Weitere Informationen finden Sie unterFeedback senden und anzeigen für