Dimensionierung der ComboBox-Dropdown-Breite
Stellt sicher, dass die Dropdown-Liste sichtbar ist, wenn die Dropdown-Liste angezeigt wird
ermingut/Getty Images
DasTComboBoxKomponente kombiniert ein Bearbeitungsfeld mit einer scrollbaren Auswahlliste. Benutzer können ein Element aus der Liste auswählen oder direkt in das eingeben Bearbeitungsfeld .
Dropdown-Liste
Wenn sich ein Kombinationsfeld im heruntergeklappten Zustand befindet, zeichnet Windows ein Steuerelement vom Typ Listenfeld, um Kombinationsfeldelemente zur Auswahl anzuzeigen.
Das DropDownCount-Eigenschaft gibt die maximale Anzahl von Elementen an, die in der Dropdown-Liste angezeigt werden.
Das Breite der Dropdown-Liste würde standardmäßig der Breite des Kombinationsfelds entsprechen.
Wenn die Länge (einer Zeichenfolge) von Elementen die Breite der Combobox überschreitet, werden die Elemente als abgeschnitten angezeigt!
TComboBox bietet keine Möglichkeit, die Breite seiner Dropdown-Liste festzulegen :(
Korrigieren der Breite der ComboBox-Dropdown-Liste
Wir können die Breite der Dropdown-Liste festlegen, indem wir ein Special senden Windows-Meldung zur Combobox. Die Nachricht ist CB_SETDROPPEDWIDTH und sendet die minimal zulässige Breite des Listenfelds eines Kombinationsfelds in Pixel.
Um die Größe der Dropdown-Liste fest auf beispielsweise 200 Pixel zu codieren, könnten Sie Folgendes tun:
|_+_|
Dies ist nur in Ordnung, wenn Sie sicher sind, dass alle Ihre theComboBox.Items nicht länger als 200 px sind (wenn gezeichnet).
Damit wir die Dropdown-Liste immer breit genug darstellen, können wir die benötigte Breite berechnen.
Hier ist eine Funktion, um die erforderliche Breite der Dropdown-Liste zu erhalten und einzustellen:
|_+_|Die Breite der längsten Zeichenfolge wird für die Breite der Dropdown-Liste verwendet.
Wann soll ComboBox_AutoWidth aufgerufen werden?
Wenn Sie die Liste der Elemente vorab ausfüllen (zur Entwurfszeit oder beim Erstellen des Formulars), können Sie die ComboBox_AutoWidth-Prozedur innerhalb des Formulars aufrufen OnCreate Ereignishandler.
Wenn Sie die Liste der Kombinationsfeldelemente dynamisch ändern, können Sie die ComboBox_AutoWidth-Prozedur innerhalb der aufrufen OnDropDown Ereignishandler – tritt auf, wenn der Benutzer die Dropdown-Liste öffnet.
Ein Test
Für einen Test haben wir 3 Kombinationsfelder auf einem Formular. Alle haben Elemente, deren Text breiter ist als die tatsächliche Breite des Kombinationsfelds. Das dritte Kombinationsfeld wird am rechten Rand des Formularrahmens platziert.
Die Items-Eigenschaft ist für dieses Beispiel vorausgefüllt – wir rufen unsere ComboBox_AutoWidth im OnCreate-Event-Handler für das Formular auf:
|_+_|Wir haben ComboBox_AutoWidth für Combobox1 nicht aufgerufen, um den Unterschied zu sehen!
Beachten Sie, dass die Dropdown-Liste für Combobox2 bei der Ausführung breiter als Combobox2 ist.
Die gesamte Dropdown-Liste wird für „Platzierung am rechten Rand“ abgeschnitten
Für Combobox3, die am rechten Rand platziert ist, ist die Dropdown-Liste abgeschnitten.
Durch das Senden von CB_SETDROPPEDWIDTH wird das Dropdown-Listenfeld immer nach rechts erweitert. Wenn sich Ihr Kombinationsfeld am rechten Rand befindet, würde das Erweitern des Listenfelds weiter nach rechts dazu führen, dass die Anzeige des Listenfelds abgeschnitten wird.
Wir müssen das Listenfeld in diesem Fall irgendwie nach links erweitern, nicht nach rechts!
CB_SETDROPPEDWIDTH hat keine Möglichkeit, anzugeben, in welche Richtung (links oder rechts) das Listenfeld erweitert werden soll.
Lösung: WM_CTLCOLORLISTBOX
Gerade wenn die Dropdown-Liste angezeigt werden soll, sendet Windows die WM_CTLCOLORLISTBOX-Nachricht an das übergeordnete Fenster einer Listbox - an unsere Combobox.
In der Lage zu sein, die WM_CTLCOLORLISTBOX für das Kombinationsfeld am rechten Rand zu handhaben, würde das Problem lösen.
Die allmächtige WindowProc
Jedes VCL-Steuerelement stellt die WindowProc-Eigenschaft bereit – die Prozedur, die auf Nachrichten antwortet, die an das Steuerelement gesendet werden. Wir können die WindowProc-Eigenschaft verwenden, um die Fensterprozedur des Steuerelements vorübergehend zu ersetzen oder eine Unterklasse zu erstellen.
Hier ist unsere modifizierte WindowProc für Combobox3 (die am rechten Rand):
|_+_|Wenn die Nachricht, die unser Kombinationsfeld erhält, WM_CTLCOLORLISTBOX ist, erhalten wir das Rechteck seines Fensters, wir erhalten auch das Rechteck des anzuzeigenden Listenfelds (GetWindowRect). Wenn es den Anschein hat, dass das Listenfeld weiter rechts erscheinen würde, verschieben wir es nach links, sodass der rechte Rand des Kombinationsfelds und des Listenfelds gleich ist. So einfach ist das :)
Wenn die Nachricht nicht WM_CTLCOLORLISTBOX ist, rufen wir einfach die ursprüngliche Nachrichtenbehandlungsprozedur für das Kombinationsfeld (ComboBox3WindowProcORIGINAL) auf.
Schließlich kann das alles funktionieren, wenn wir es richtig eingestellt haben (im OnCreate-Ereignishandler für das Formular):
|_+_|Wo in der Erklärung des Formulars haben wir (vollständig):
|_+_|Und das ist es. Alles erledigt :)