Cum să adăugați casete de selectare și butoane radio la un TTreeView

Componenta TTreeView Delphi (localizată în fila paletei de componente „Win32”) reprezintă o fereastră care afișează o listă ierarhică de elemente, cum ar fi titlurile dintr-un document, intrările dintr-un index sau fișierele și directoarele de pe un disc..

Nod arbore cu casetă de selectare sau buton radio?

Delphi TTreeview nu acceptă în mod original casetele de selectare, dar controlul WC_TREEVIEW de bază îl face. Puteți adăuga căsuțe de selectare la vizualizarea arborelui suprasolicitând procedura CreateParams a TTreeView, specificând stilul TVS_CHECKBOXES pentru control. Rezultatul este că toate nodurile din viewview tree vor avea casetele de selectare atașate la ele. În plus, proprietatea StateImages nu mai poate fi utilizată deoarece WC_TREEVIEW folosește această imagelistă intern pentru a implementa casetele de selectare. Dacă doriți să comutați casetele de selectare, va trebui să faceți acest lucru folosind Trimite mesaj sau Macro-uri TreeView_SetItem / TreeView_GetItem din CommCtrl.pas. WC_TREEVIEW acceptă doar căsuțele de selectare, nu și butoanele radio.

Abordarea pe care o veți descoperi în acest articol este mult mai flexibilă: puteți avea casetele de selectare și butoanele radio, amestecate cu alte noduri, în orice mod doriți, fără a schimba TTreeview sau a crea o nouă clasă din acesta pentru a face acest lucru. De asemenea, vă decideți ce imagini să utilizați pentru casetele de selectare / butoanele radio pur și simplu adăugând imagini potrivite în imagelistul StateImages.

Adăugați o casetă de selectare sau buton radio

Contrar a ceea ce s-ar putea crede, acest lucru este destul de simplu de realizat în Delphi. Iată pașii pentru ca acesta să funcționeze:

  1. Configurați o listă de imagini (componenta TImageList din fila paletei de componente „Win32”) pentru proprietatea TTreeview.StateImages care conține imaginile pentru starea (cele) bifate / necherificate pentru casetele de selectare și / sau butoanele radio..
  2. Apelați procedura ToggleTreeViewCheckBoxes (a se vedea mai jos) în evenimentele OnClick și OnKeyDown din viewview. Procedura ToggleTreeViewCheckBoxes modifică StateIndex al nodului selectat pentru a reflecta starea actuală verificată / debifată.

Pentru a face vizionarea arborelui și mai profesională, ar trebui să verificați unde se face clic pe un nod înainte de a comuta imaginile de stat: doar comutând nodul când faceți clic pe imaginea reală, utilizatorii dvs. pot încă să selecteze nodul fără a-i schimba starea..

În plus, dacă nu doriți ca utilizatorii dvs. să extindă / să prăbușească vizualizarea în arbore, apelați la procedura FullExpand în formularul Evenimentul OnShow și setați AllowCollapse la false în evenimentul TreeCollapsing.

Iată implementarea procedurii ToggleTreeViewCheckBoxes:

procedură ToggleTreeViewCheckBoxes (
Nod: TTreeNode;
cUnChecked,
cChecked,
cRadioUnchecked,
cRadioChecked: număr întreg);
var
tmp: TTreeNode;
beginif Atribuit (Node) thenbeginif Node.StateIndex = cUnChecked apoi
Node.StateIndex: = cChecked
altfel dacă Node.StateIndex = cChecked apoi
Node.StateIndex: = cUnChecked
altfel dacă Node.StateIndex = cRadioUnChecked thenbegin
tmp: = Nod.Parent;
dacă nu Atribuit (tmp) apoi
tmp: = TTreeView (Node.TreeView) .Items.getFirstNode
altfel
tmp: = tmp.getFirstChild;
in timp ce Atribuit (tmp) dobeginif (tmp.StateIndex în
[CRadioUnChecked, cRadioChecked]) apoi
tmp.StateIndex: = cRadioUnChecked;
tmp: = tmp.getNextSibling;
Sfârșit;
Node.StateIndex: = cRadioChecked;
Sfârșit; // dacă StateIndex = cRadioUnCheckedSfârșit; // dacă este alocat (nod)
Sfârșit; (* ToggleTreeViewCheckBoxes *)

După cum puteți vedea din codul de mai sus, procedura începe prin a găsi orice noduri pentru caseta de selectare și doar comutarea acestora pe sau dezactivat. În continuare, dacă nodul este un buton radio necherificat, procedura se mută la primul nod de la nivelul curent, stabilește toate nodurile de pe acel nivel la cRadioUnchecked (dacă sunt noduri cRadioUnChecked sau cRadioChecked) și în final comută nodul la cRadioChecked.

Observați cum orice butoane radio deja verificate sunt ignorate. Evident, acest lucru se datorează faptului că un buton radio deja bifat ar fi comutat până la bifat, lăsând nodurile într-o stare nedefinită. Aproape ce ți-ai dori de cele mai multe ori.

Iată cum să faceți codul și mai profesional: în evenimentul OnClick al Treeview, scrieți următorul cod pentru a comuta doar căsuțele de selectare dacă s-a făcut clic pe imaginea de stat (constantele cFlatUnCheck, cFlatChecked etc sunt definite în altă parte ca indexuri în lista de imagini StateImages) :

procedură TForm1.TreeView1Click (Expeditor: TObject);
var
P: TPoint;
începe
GetCursorPos (P);
P: = TreeView1.ScreenToClient (P);
dacă (htOnStateIcon în
TreeView1.GetHitTestInfoAt (P.X, P.Y)) apoi
ToggleTreeViewCheckBoxes (
TreeView1.Selected,
cFlatUnCheck,
cFlatChecked,
cFlatRadioUnCheck,
cFlatRadioChecked);
Sfârșit; (* TreeView1Click *)

Codul primește poziția curentă a mouse-ului, se transformă în coordonatele de vizualizare arbore și verifică dacă a fost făcut clic pe StateIcon apelând funcția GetHitTestInfoAt. Dacă a fost, se apelează la procedura de comutare.

În mare parte, vă așteptați ca bara spațială să comute casetele de selectare sau butoanele radio, așa că iată cum se scrie evenimentul TreeView OnKeyDown folosind acel standard:

procedură TForm1.TreeView1KeyDown (
Expeditor: TObject;
var Cheie: Cuvânt;
Shift: TShiftState);
beginif (Cheie = VK_SPACE) și
Atribuit (TreeView1.Selected) apoi
ToggleTreeViewCheckBoxes (
TreeView1.Selected,
cFlatUnCheck,
cFlatChecked,
cFlatRadioUnCheck,
cFlatRadioChecked);
Sfârșit; (* TreeView1KeyDown *)

În cele din urmă, iată cum ar putea arăta evenimentele OnShow ale formularelor și Arborele OnChanging dacă doriți să împiedicați colapsul nodurilor arborelui:

procedură TForm1.FormCreate (Expeditor: TObject);
începe
TreeView1.FullExpand;
Sfârșit; (* FormCreate *)
procedură TForm1.TreeView1Collapsing (
Expeditor: TObject;
Nod: TTreeNode;
var AllowCollapse: Boolean);
începe
AllowCollapse: = fals;
Sfârșit; (* TreeView1Collapsing *)

În cele din urmă, pentru a verifica dacă un nod este bifat, faceți pur și simplu următoarea comparație (de exemplu, într-un instrument de gestionare a evenimentelor OnClick):

procedură TForm1.Button1Click (Expeditor: TObject);
var
BoolResult: boolean;
tn: TTreeNode;
beginif Atribuit (TreeView1.Selected) thenbegin
tn: = TreeView1.Selected;
BoolResult: = tn.StateIndex în
[CFlatChecked, cFlatRadioChecked];
Memo1.Text: = tn.Text +
# 13 # 10 +
'Selectat: ' +
BoolToStr (BoolResult, True);
Sfârșit;
Sfârșit; (* Button1Click *)

Deși acest tip de codificare nu poate fi considerat ca fiind esențial pentru misiune, acesta poate oferi aplicațiilor tale un aspect mai profesional și mai lin. De asemenea, folosind casetele de selectare și butoanele radio în mod prudent, acestea pot face aplicația dvs. mai ușor de utilizat. Cu siguranță vor arăta bine!

Această imagine de mai jos a fost preluată dintr-o aplicație de testare folosind codul descris în acest articol. După cum vedeți, puteți amesteca liber nodurile care au casete de selectare sau butoane radio cu cele care nu au niciunul, deși nu ar trebui să amestecați noduri „goale” cu noduri „caseta de selectare” (aruncați o privire la butoanele radio din imagine), deoarece aceasta face foarte greu să vezi ce noduri sunt înrudite.