Il componente TTreeView Delphi (situato nella scheda della tavolozza dei componenti "Win32") rappresenta una finestra che visualizza un elenco gerarchico di elementi, come le intestazioni in un documento, le voci in un indice o i file e le directory su un disco.
Nodo dell'albero con casella di controllo o pulsante di opzione?
La TTreeview di Delphi non supporta nativamente le caselle di controllo ma il controllo WC_TREEVIEW sottostante lo fa. È possibile aggiungere caselle di controllo a visualizzazione ad albero sovrascrivendo la procedura CreateParams di TTreeView, specificando lo stile TVS_CHECKBOXES per il controllo. Il risultato è tutto nodi nella treeview saranno collegate delle caselle di controllo. Inoltre, la proprietà StateImages non può più essere utilizzata perché WC_TREEVIEW utilizza questa lista immagini internamente per implementare le caselle di controllo. Se vuoi attivare / disattivare le caselle di controllo, dovrai farlo utilizzando Invia messaggio o il Macro TreeView_SetItem / TreeView_GetItem
a partire dal CommCtrl.pas. WC_TREEVIEW supporta solo caselle di controllo, non pulsanti di opzione.L'approccio che devi scoprire in questo articolo è molto più flessibile: puoi avere caselle di controllo e pulsanti di opzione mescolati con altri nodi come preferisci senza modificare la visualizzazione TT o crearne uno nuovo classe da esso per farlo funzionare. Inoltre, decidi tu stesso quali immagini utilizzare per le caselle di controllo / pulsanti radio semplicemente aggiungendo le immagini appropriate all'immagine di StateImages.
Aggiungi una casella di controllo o un pulsante di opzione
Contrariamente a quanto potresti credere, questo è abbastanza semplice da realizzare Delphi. Ecco i passaggi per farlo funzionare:
- Impostare un elenco di immagini (componente TImageList nella scheda della palette dei componenti "Win32") per la vista TT. Proprietà StateImages contenente le immagini per gli stati selezionati e non selezionati per caselle di controllo e / o pulsanti di opzione.
- Chiamare la procedura ToggleTreeViewCheckBoxes (vedere di seguito) negli eventi OnClick e OnKeyDown del treeview. La procedura ToggleTreeViewCheckBoxes modifica StateIndex del nodo selezionato per riflettere lo stato corrente selezionato / non controllato.
Per rendere la tua treeview ancora più professionale, dovresti controllare dove si fa clic su un nodo prima di attivare / disattivare le immagini di stato: alternando il nodo solo quando si fa clic sull'immagine effettiva, gli utenti possono comunque selezionare il nodo senza modificarne stato.
Inoltre, se non si desidera che gli utenti espandano / comprimano il treeview, chiamare la procedura FullExpand nell'evento OnShow dei moduli e impostare AllowCollapse su false nell'evento OnCollapsing del treeview.
Ecco l'implementazione della procedura ToggleTreeViewCheckBoxes:
procedura ToggleTreeViewCheckBoxes (
Nodo: TTreeNode;
cUnChecked,
cChecked,
cRadioUnchecked,
cRadioChecked: intero);
var
tmp: TTreeNode;
beginif Assegnato (nodo) thenbeginif Nodo. StateIndex = cUnChecked poi
Nodo. StateIndex: = cChecked
altroSe Nodo. StateIndex = cChecked poi
Nodo. StateIndex: = cUnChecked
altro se Nodo. StateIndex = cRadioUnChecked thenbegin
tmp: = nodo. Genitore;
altrimenti Assegnato (tmp) poi
tmp: = TTreeView (Nodo. TreeView) .Items.getFirstNode
altro
tmp: = tmp.getFirstChild;
mentre Assegnato (tmp) dobeginif (Tmp. StateIndex nel
[cRadioUnChecked, cRadioChecked]) poi
tmp. StateIndex: = cRadioUnChecked;
tmp: = tmp.getNextSibling;
fine;
Nodo. StateIndex: = cRadioChecked;
fine; // se StateIndex = cRadioUnCheckedfine; // se assegnato (nodo)
fine; (* ToggleTreeViewCheckBoxes *)
Come puoi vedere dal codice sopra, la procedura inizia trovando tutti i nodi della casella di controllo e semplicemente attivandoli o disattivandoli. Successivamente, se il nodo è un pulsante di opzione non selezionato, la procedura si sposta sul primo nodo al livello corrente, imposta tutti i nodi su quel livello su cRadioUnchecked (se sono nodi cRadioUnChecked o cRadioChecked) e infine attiva Nodo su cRadioChecked.
Notare come i pulsanti di opzione già selezionati vengono ignorati. Ovviamente, questo perché un pulsante di opzione già selezionato verrebbe disattivato, lasciando i nodi in uno stato indefinito. Difficilmente quello che vorresti la maggior parte del tempo.
Ecco come rendere il codice ancora più professionale: nell'evento OnClick di Treeview, scrivi il codice seguente per attivare caselle di controllo se è stato fatto clic sullo stato dell'immagine (le costanti cFlatUnCheck, cFlatChecked ecc sono definite altrove come indici negli StateImages elenco di immagini):
procedura TForm1.TreeView1Click (Mittente: TObject);
var
P: TPoint;
inizio
GetCursorPos (P);
P: = TreeView1.ScreenToClient (P);
Se (htOnStateIcon nel
TreeView1.GetHitTestInfoAt (P.X, P.Y)) poi
ToggleTreeViewCheckBoxes (
TreeView1.Selected,
cFlatUnCheck,
cFlatChecked,
cFlatRadioUnCheck,
cFlatRadioChecked);
fine; (* TreeView1Click *)
Il codice ottiene la posizione corrente del mouse, si converte in coordinate treeview e verifica se è stato fatto clic su StateIcon chiamando la funzione GetHitTestInfoAt. In tal caso, viene chiamata la procedura di attivazione / disattivazione.
Per lo più, ti aspetteresti che la barra spaziatrice commuti le caselle di controllo o i pulsanti di opzione, quindi ecco come scrivere l'evento TreeView OnKeyDown usando quello standard:
procedura TForm1.TreeView1KeyDown (
Mittente: TObject;
var chiave: Word;
Maiusc: TShiftState);
beginif (Key = VK_SPACE) e
Assegnato (TreeView1.Selected) poi
ToggleTreeViewCheckBoxes (
TreeView1.Selected,
cFlatUnCheck,
cFlatChecked,
cFlatRadioUnCheck,
cFlatRadioChecked);
fine; (* TreeView1KeyDown *)
Infine, ecco come potrebbero apparire gli eventi OnShow del modulo e OnChanging di Treeview se si volesse impedire il collasso dei nodi del treeview:
procedura TForm1.FormCreate (Mittente: TObject);
inizio
TreeView1.FullExpand;
fine; (* FormCreate *)
procedura TForm1.TreeView1Collapsing (
Mittente: TObject;
Nodo: TTreeNode;
var AllowCollapse: Boolean);
inizio
AllowCollapse: = false;
fine; (* TreeView1Collapsing *)
Infine, per verificare se un nodo è selezionato, devi semplicemente fare il seguente confronto (ad esempio nel gestore di eventi OnClick di Button):
procedura TForm1.Button1Click (Mittente: TObject);
var
BoolResult: boolean;
tn: TTreeNode;
beginif Assegnato (TreeView1.Selected) thenbegin
tn: = TreeView1.Selected;
BoolResult: = tn. StateIndex nel
[cFlatChecked, cFlatRadioChecked];
Memo1.Text: = tn. Testo +
#13#10 +
'Selezionato:' +
BoolToStr (BoolResult, True);
fine;
fine; (* Button1Click *)
Sebbene questo tipo di codifica non possa essere considerato mission-critical, può dare alle tue applicazioni un aspetto più professionale e fluido. Inoltre, utilizzando le caselle di controllo e i pulsanti di opzione in modo giudizioso, possono semplificare l'utilizzo dell'applicazione. Di sicuro staranno bene!
L'immagine seguente è stata presa da un'app di test usando il codice descritto in questo articolo. Come puoi vedere, puoi mescolare liberamente nodi con caselle di controllo o pulsanti di opzione con quelli che non ne hanno, anche se non dovresti mescolare nodi "vuoti" con "casella di controllo"nodi (dai un'occhiata ai pulsanti di opzione nell'immagine) in quanto ciò rende molto difficile vedere quali nodi sono correlati.