TreeView Cu casete de selectare și butoane radio

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

Nod arbore cu caseta 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 TreeView prin prescurtarea procedurii CreateParams a TTreeView, specificând stilul TVS_CHECKBOXES pentru control. Rezultatul este că toate noduri în arborele de vedere vor avea casetele de selectare atașate de 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.

instagram viewer

Abordarea pe care o veți descoperi în acest articol este mult mai flexibilă: puteți avea căsuțe de selectare și butoanele radio amestecate cu alte noduri, cum doriți, fără a modifica TTreeview sau a crea un nou clasă din ea pentru a face această lucrare. De asemenea, vă decideți ce imagini să utilizați pentru casetele de selectare / butoanele radio pur și simplu adăugând imagini potrivite imagelistului StateImages.

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

Spre deosebire de ceea ce ai putea crede, acest lucru este destul de simplu de realizat 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 TTreeview. Proprietate StateImages care conține imaginile pentru starea (cele) bifate și 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ă / necherificată.

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

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

Iată implementarea procedurii ToggleTreeViewCheckBoxes:

procedură ToggleTreeViewCheckBoxes (
Nod: TTreeNode;
cUnChecked,
cChecked,
cRadioUnchecked,
cRadioChecked: număr întreg);
var
tmp: TTreeNode;
beginif Atribuit (nod) thenbeginif Nodul. StateIndex = cUnChecked apoi
Nodul. StateIndex: = cChecked
altfeldacă Nodul. StateIndex = cChecked apoi
Nodul. StateIndex: = cUnChecked
altfel dacă Nodul. StateIndex = cRadioUnChecked thenbegin
tmp: = nod. Mamă;
dacă nu Atribuit (tmp) apoi
tmp: = TTreeView (Nod. 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;
Nodul. 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 nemarcat, procedura se mută la primul nod de la nivelul curent, setează toate nodurile pe acel nivel la cRadioUnchecked (dacă sunt noduri cRadioUnChecked sau cRadioChecked) și în final comută Node 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 din Treeview, scrieți următorul cod pentru a comuta doar casetele de selectare dacă s-a făcut clic pe imaginea de stat (constantele cFlatUnCheck, cFlatChecked etc sunt definite în altă parte ca indexuri în StateImages lista de imagini):

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 principal, 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 formularului ș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 sfârșit, 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 facilita utilizarea aplicației. 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 trebuie să amestecați nodurile „goale” cu „Caseta de bifat"noduri (aruncați o privire la butoanele radio din imagine) deoarece acest lucru face foarte greu să vedeți ce noduri sunt legate.