TreeView med avmerkingsbokser og radioknapper

click fraud protection

TTreeView Delphi-komponenten (plassert på "Win32" -komponentpalettfanen) representerer et vindu som viser et hierarkisk liste over elementer, for eksempel overskriftene i et dokument, oppføringene i en indeks eller filene og katalogene på en disk.

Treknute med avmerkingsboks eller radioknapp?

Delphis TTreeview støtter ikke avkrysningsbokser, men den underliggende WC_TREEVIEW-kontrollen gjør det. Du kan legge til avmerkingsbokser i tre utsikt ved å overstyre CreateParams-prosedyren for TTreeView, og spesifisere TVS_CHECKBOXES-stilen for kontrollen. Resultatet er at alt noder i utsikten vil ha avkrysningsruter knyttet til seg. I tillegg kan ikke StateImages-egenskapen brukes lenger fordi WC_TREEVIEW bruker denne forestillingen internt for å implementere avmerkingsbokser. Hvis du vil veksle i avmerkingsboksene, må du gjøre det ved å bruke Sende melding eller TreeView_SetItem / TreeView_GetItem-makroer fra CommCtrl.pas. WC_TREEVIEW støtter bare avmerkingsbokser, ikke radioknapper.

Tilnærmingen du skal oppdage i denne artikkelen er mye mer fleksibel: du kan ha avmerkingsbokser og radioknapper blandet med andre noder slik du måtte ønske uten å endre TTrevisningen eller opprette en ny

instagram viewer
klasse fra det for å få dette til å fungere. Du bestemmer deg selv hvilke bilder du vil bruke til avmerkingsboksene / radioknappene bare ved å legge de riktige bildene til StateImages-forestillingen.

Legg til en avmerkingsboks eller radioknapp

I motsetning til hva du kanskje tror, ​​er dette ganske enkelt å oppnå Delphi. Her er trinnene for å få det til å fungere:

  1. Sett opp en bildeliste (TImageList-komponent på "Win32" -komponentpalettfanen) for TTreeview. StateImages-egenskapen som inneholder bilder for avmerkede og ikke-avmerkede tilstander for avmerkingsbokser og / eller radioknapper.
  2. Ring prosedyren ToggleTreeViewCheckBoxes (se nedenfor) i hendelsene OnClick og OnKeyDown i treeview. ToggleTreeViewCheckBoxes-prosedyren endrer StateIndex for den valgte noden for å gjenspeile den gjeldende kontrollerte / ukontrollerte tilstanden.

For å gjøre treevisningen din enda mer profesjonell, bør du sjekke hvor en node er klikket før du bytter på statlige bilder: ved å bare slå på noden når det klikkes på det faktiske bildet, kan brukerne dine fortsatt velge noden uten å endre den stat.

Hvis du ikke vil at brukerne dine skal utvide / kollaps treevisningen, kan du ringe FullExpand-prosedyren i skjemaene OnShow-hendelse og sette AllowCollapse til falsk i Treeviews OnCollapsing-hendelse.

Her er implementeringen av ToggleTreeViewCheckBoxes-prosedyren:

fremgangsmåte ToggleTreeViewCheckBoxes (
Node: TTreeNode;
cUnChecked,
cChecked,
cRadioUnchecked,
cRadioChecked: heltall);
Var
tmp: TTreeNode;
beginif Tildelt (node) thenbeginif Node. StateIndex = cUnChecked deretter
Node. StateIndex: = cChecked
ellershvis Node. StateIndex = cChecked deretter
Node. StateIndex: = cUnChecked
eller hvis Node. StateIndex = cRadioUnChecked thenbegin
tmp: = Knutepunkt. forelder;
Hvis ikke Tildelt (tmp) deretter
tmp: = TTreeView (Node. Treeview) .Items.getFirstNode
ellers
tmp: = tmp.getFirstChild;
samtidig som Tildelt (tmp) dobeginif (Tmp. StateIndex i
[cRadioUnChecked, cRadioChecked]) deretter
tmp. StateIndex: = cRadioUnChecked;
tmp: = tmp.getNextSibling;
slutt;
Node. StateIndex: = cRadioChecked;
slutt; // hvis StateIndex = cRadioUnCheckedslutt; // hvis tilordnet (node)
slutt; (* ToggleTreeViewCheckBoxes *)

Som du ser av koden over, starter prosedyren med å finne eventuelle avkrysningsrutenoder og bare slå dem av eller på. Neste, hvis noden er en ikke-merket alternativknapp, flytter prosedyren til den første noden på det nåværende nivået, angir alle nodene på det nivået til cRadioUnchecked (hvis de er cRadioUnChecked eller cRadioChecked nodes) og endelig bytter Node til cRadioChecked.

Legg merke til hvordan allerede kontrollerte radioknapper blir ignorert. Dette er åpenbart fordi en allerede kontrollert alternativknapp vil bli slått på til ikke-avkrysset og la knutepunktene i en udefinert tilstand. Neppe det du ønsker mest av tiden.

Slik gjør du koden enda mer profesjonell: i OnClick-hendelsen i Treeview, skriv følgende kode for bare å slå på avkrysningsbokser hvis det ble klikket på statlige bilder (konstantene cFlatUnCheck, cFlatChecked osv. er definert andre steder som indekser til statenImages bildeliste):

fremgangsmåte TForm1.TreeView1Klikk (avsender: TObject);
Var
P: TPoint;
begynne
GetCursorPos (P);
P: = TreeView1.ScreenToClient (P);
hvis (htOnStateIcon i
TreeView1.GetHitTestInfoAt (P.X, P.Y)) deretter
ToggleTreeViewCheckBoxes (
TreeView1.Selected,
cFlatUnCheck,
cFlatChecked,
cFlatRadioUnCheck,
cFlatRadioChecked);
slutt; (* TreeView1Click *)

Koden får den gjeldende museposisjonen, konverteres til treeview-koordinater og sjekker om StateIcon ble klikket ved å ringe GetHitTestInfoAt-funksjonen. Hvis det var det, kalles vekslingsprosedyren.

Stort sett kan du forvente at mellomromstasten veksler av avmerkingsbokser eller radioknapper, så her skriver du hvordan du skriver TreeView OnKeyDown-hendelsen ved å bruke denne standarden:

fremgangsmåte TForm1.TreeView1KeyDown (
Avsender: TObject;
var Nøkkel: Word;
Skift: TShiftState);
beginif (Nøkkel = VK_SPACE) og
Tildelt (TreeView1.Selected) deretter
ToggleTreeViewCheckBoxes (
TreeView1.Selected,
cFlatUnCheck,
cFlatChecked,
cFlatRadioUnCheck,
cFlatRadioChecked);
slutt; (* TreeView1KeyDown *)

Til slutt, her er hvordan skjemaets OnShow og Treeviews OnChanging-hendelser kan se ut hvis du ville forhindre kollaps av treeviewens noder:

fremgangsmåte TForm1.FormCreate (avsender: TObject);
begynne
TreeView1.FullExpand;
slutt; (* FormCreate *)
fremgangsmåte TForm1.TreeView1Collapsing (
Avsender: TObject;
Node: TTreeNode;
Var AllowCollapse: Boolean);
begynne
AllowCollapse: = falsk;
slutt; (* TreeView1Collapsing *)

Til slutt, for å sjekke om en node er sjekket, gjør du ganske enkelt følgende sammenligning (i en Buttons OnClick-hendelsesbehandler, for eksempel):

fremgangsmåte TForm1.Button1Click (avsender: TObject);
Var
BoolResult: boolean;
tn: TTreeNode;
beginif Tildelt (TreeView1.Selected) thenbegin
tn: = TreeView1.Velget;
BoolResult: = tn. StateIndex i
[cFlatChecked, cFlatRadioChecked];
Memo1.Text: = tn. Tekst +
#13#10 +
'Valgt:' +
BoolToStr (BoolResult, True);
slutt;
slutt; (* Button1Click *)

Selv om denne typen koding ikke kan betraktes som oppdragskritisk, kan den gi applikasjonene dine et mer profesjonelt og jevnere utseende. Ved å bruke avmerkingsboksene og radioknappene med omhu, kan de gjøre applikasjonen din enklere å bruke. De vil helt sikkert se bra ut!

Dette bildet nedenfor er hentet fra en testapp ved bruk av koden beskrevet i denne artikkelen. Som du kan se, kan du fritt blande noder med avmerkingsbokser eller alternativknapper med de som ikke har noen, selv om du ikke bør blande "tomme" noder med "avkrysnings"noder (se på alternativknappene i bildet), da dette gjør det veldig vanskelig å se hvilke noder som er relatert.

instagram story viewer