So fügen Sie einem TTreeView Kontrollkästchen und Optionsfelder hinzu

Die TTreeView Delphi-Komponente (auf der Registerkarte "Win32" -Komponentenpalette) stellt ein Fenster dar, in dem eine hierarchische Liste von Elementen angezeigt wird, z. B. die Überschriften in einem Dokument, die Einträge in einem Index oder die Dateien und Verzeichnisse auf einer Festplatte.

Baumknoten mit Kontrollkästchen oder Optionsfeld?

Delphis TTreeview unterstützt keine Kontrollkästchen, das zugrunde liegende WC_TREEVIEW-Steuerelement jedoch. Sie können der Strukturansicht Kontrollkästchen hinzufügen, indem Sie die CreateParams-Prozedur von TTreeView überschreiben und den TVS_CHECKBOXES-Stil für das Steuerelement angeben. Das Ergebnis ist, dass allen Knoten in der Strukturansicht Kontrollkästchen zugeordnet sind. Darüber hinaus kann die StateImages-Eigenschaft nicht mehr verwendet werden, da WC_TREEVIEW diese Imageliste intern zum Implementieren von Kontrollkästchen verwendet. Wenn Sie die Kontrollkästchen umschalten möchten, müssen Sie dies mit tun Nachricht senden oder der TreeView_SetItem / TreeView_GetItem-Makros von CommCtrl.pas. Das WC_TREEVIEW unterstützt nur Kontrollkästchen, keine Optionsfelder.

Der Ansatz, den Sie in diesem Artikel finden, ist wesentlich flexibler: Sie können Kontrollkästchen und Optionsfelder beliebig mit anderen Knoten mischen, ohne die TTreeview zu ändern oder eine neue Klasse daraus zu erstellen, damit dies funktioniert. Sie können auch selbst entscheiden, welche Bilder für die Kontrollkästchen / Radiobuttons verwendet werden sollen, indem Sie einfach die richtigen Bilder zur Bildliste von StateImages hinzufügen.

Fügen Sie ein Kontrollkästchen oder ein Optionsfeld hinzu

Anders als Sie vielleicht glauben, ist dies in Delphi ganz einfach zu bewerkstelligen. Hier sind die Schritte, damit es funktioniert:

  1. Richten Sie eine Bilderliste (TImageList-Komponente auf der Registerkarte "Win32" -Komponentenpalette) für die TTreeview.StateImages-Eigenschaft ein, die die Bilder für die aktivierten und deaktivierten Status für Kontrollkästchen und / oder Optionsfelder enthält.
  2. Rufen Sie die ToggleTreeViewCheckBoxes-Prozedur (siehe unten) in den OnClick- und OnKeyDown-Ereignissen der Strukturansicht auf. Die ToggleTreeViewCheckBoxes-Prozedur ändert den StateIndex des ausgewählten Knotens, um den aktuellen aktivierten / deaktivierten Status wiederzugeben.

Um Ihre Baumansicht noch professioneller zu gestalten, sollten Sie vor dem Umschalten der Statusbilder prüfen, wo auf einen Knoten geklickt wird: Wenn Sie den Knoten nur umschalten, wenn auf das tatsächliche Bild geklickt wird, können Ihre Benutzer den Knoten dennoch auswählen, ohne seinen Status zu ändern.

Wenn Sie nicht möchten, dass Ihre Benutzer die Strukturansicht erweitern / reduzieren, rufen Sie die FullExpand-Prozedur im Forms OnShow-Ereignis auf und setzen Sie AllowCollapse im OnCollapsing-Ereignis der Strukturansicht auf false.

Hier ist die Implementierung der ToggleTreeViewCheckBoxes-Prozedur:

Verfahren ToggleTreeViewCheckBoxes (
Knoten: TTreeNode;
cUnChecked,
cGecheckt,
cRadioUnchecked,
cRadioChecked: integer);
var
tmp: TTreeNode;
beginif Zugewiesen (Knoten) thenbeginif Node.StateIndex = cUnChecked dann
Node.StateIndex: = cChecked
sonst wenn Node.StateIndex = cChecked dann
Node.StateIndex: = cUnChecked
sonst wenn Node.StateIndex = cRadioUnChecked dann fange an
tmp: = Node.Parent;
wenn nicht Zugewiesen (tmp) dann
tmp: = TTreeView (Node.TreeView) .Items.getFirstNode
sonst
tmp: = tmp.getFirstChild;
während Zugewiesen (tmp) Dobeginif (tmp.StateIndex im
[cRadioUnChecked, cRadioChecked]) dann
tmp.StateIndex: = cRadioUnChecked;
tmp: = tmp.getNextSibling;
Ende;
Node.StateIndex: = cRadioChecked;
Ende; // if StateIndex = cRadioUnCheckedEnde; // wenn zugewiesen (Knoten)
Ende; (* ToggleTreeViewCheckBoxes *)

Wie Sie aus dem obigen Code ersehen können, beginnt der Vorgang damit, dass Sie alle Kontrollkästchen-Knoten finden und sie ein- oder ausschalten. Wenn es sich bei dem Knoten um ein nicht ausgewähltes Optionsfeld handelt, wechselt die Prozedur zum ersten Knoten auf der aktuellen Ebene, setzt alle Knoten auf dieser Ebene auf cRadioUnchecked (wenn es sich um cRadioUnChecked- oder cRadioChecked-Knoten handelt) und wechselt schließlich zwischen Node und cRadioChecked.

Beachten Sie, wie bereits aktivierte Optionsfelder ignoriert werden. Dies liegt offensichtlich daran, dass ein bereits angekreuztes Optionsfeld deaktiviert ist und die Knoten in einem undefinierten Zustand verbleiben. Kaum das, was Sie sich die meiste Zeit wünschen würden.

So machen Sie den Code noch professioneller: Schreiben Sie im OnClick-Ereignis von Treeview den folgenden Code, um die Kontrollkästchen nur dann umzuschalten, wenn auf das Statusbild geklickt wurde (die Konstanten cFlatUnCheck, cFlatChecked usw. sind an anderer Stelle als Indizes in der Statusbildliste definiert). :

Verfahren TForm1.TreeView1Click (Absender: TObject);
var
P: TPoint;
Start
GetCursorPos (P);
P: = TreeView1.ScreenToClient (P);
wenn (htOnStateIcon im
TreeView1.GetHitTestInfoAt (P.X, P.Y)) dann
ToggleTreeViewCheckBoxes (
TreeView1.Selected,
cFlatUnCheck,
cFlatChecked,
cFlatRadioUnCheck,
cFlatRadioChecked);
Ende; (* TreeView1Click *)

Der Code ruft die aktuelle Mausposition ab, konvertiert in Baumstrukturkoordinaten und überprüft, ob das StateIcon durch Aufrufen der GetHitTestInfoAt-Funktion angeklickt wurde. Wenn ja, wird die Umschaltprozedur aufgerufen.

In den meisten Fällen würde man erwarten, dass die Leertaste Kontrollkästchen oder Optionsfelder umschaltet. So schreiben Sie das TreeView OnKeyDown-Ereignis mit diesem Standard:

Verfahren TForm1.TreeView1KeyDown (
Absender: TObject;
var Schlüssel: Word;
Shift: TShiftState);
beginif (Schlüssel = VK_SPACE) und
Zugewiesen (TreeView1.Selected) dann
ToggleTreeViewCheckBoxes (
TreeView1.Selected,
cFlatUnCheck,
cFlatChecked,
cFlatRadioUnCheck,
cFlatRadioChecked);
Ende; (* TreeView1KeyDown *)

Zum Schluss können die OnShow- und OnChanging-Ereignisse des Formulars so aussehen, wenn Sie verhindern möchten, dass die Knoten des Baums zusammenfallen:

Verfahren TForm1.FormCreate (Absender: TObject);
Start
TreeView1.FullExpand;
Ende; (* FormCreate *)
Verfahren TForm1.TreeView1Collapsing (
Absender: TObject;
Knoten: TTreeNode;
var AllowCollapse: Boolean);
Start
AllowCollapse: = false;
Ende; (* TreeView1Collapsing *)

Um zu überprüfen, ob ein Knoten markiert ist, führen Sie einfach den folgenden Vergleich durch (z. B. in der OnClick-Ereignisbehandlungsroutine eines Buttons):

Verfahren TForm1.Button1Click (Absender: TObject);
var
BoolResult: boolean;
tn: TTreeNode;
beginif Zugewiesen (TreeView1.Selected) dann fange an
tn: = TreeView1.Selected;
BoolResult: = tn.StateIndex im
[cFlatChecked, cFlatRadioChecked];
Memo1.Text: = tn.Text +
# 13 # 10 +
'Ausgewählt: ' +
BoolToStr (BoolResult, True);
Ende;
Ende; (* Button1Click *)

Obwohl diese Art der Codierung nicht als geschäftskritisch angesehen werden kann, können Ihre Anwendungen dadurch professioneller und reibungsloser aussehen. Wenn Sie die Kontrollkästchen und Optionsfelder mit Bedacht verwenden, können Sie außerdem die Verwendung Ihrer Anwendung vereinfachen. Sie werden sicher gut aussehen!

Das folgende Bild wurde mit dem in diesem Artikel beschriebenen Code aus einer Test-App entnommen. Wie Sie sehen, können Sie Knoten mit Ankreuzfeldern oder Optionsfeldern mit Knoten ohne Ankreuzfeldern beliebig mischen, obwohl Sie "leere" Knoten nicht mit "Ankreuzfeldern" Knoten mischen sollten (siehe die Optionsfelder im Bild) macht es sehr schwer zu sehen, welche Knoten zusammenhängen.