TreeView с квадратчета за отметка и радио бутони

Компонентът TTreeView Delphi (намира се в раздела от палитрата на компонентите "Win32") представлява прозорец, който показва йерархичен списък на елементи, като заглавия в документ, записи в индекс или файлове и директории в диск.

Възел на дърво с квадратче за отметка или радио бутон?

TTreeview на Delphi не поддържа първоначално отметките, но съответният WC_TREEVIEW контрол прави. Можете да добавите квадратчета за отметка към дървовидна структура чрез отмяна на процедурата CreateParams на TTreeView, посочване на стила TVS_CHECKBOXES за контрола. Резултатът е, че всички възли в дървесния изглед ще има закачени квадратчета за отметки към тях. В допълнение, свойството StateImages не може да бъде използвано повече, тъй като WC_TREEVIEW използва този списък с изображения за вътрешна реализация на отметки. Ако искате да превключите квадратчетата за отметки, ще трябва да го направите, като използвате Изпрати съобщение или TreeView_SetItem / TreeView_GetItem макроси от CommCtrl.pas. WC_TREEVIEW поддържа само отметки, а не радио бутони.

instagram viewer

Подходът, който трябва да откриете в тази статия, е много по-гъвкав: можете да имате квадратчета за отметки и радио бутони, смесени с други възли, както желаете, без да променяте TTreeview или да създавате нов клас от него, за да направя тази работа. Освен това сами решавате какви изображения да използвате за квадратчетата / радиобутоните, просто като добавите подходящите изображения към списъка с изображения на StateImages.

Добавете квадратче за отметка или радио бутон

Противно на това, което може би вярвате, това е доста лесно да се постигне Delphi. Ето стъпките, за да го направите:

  1. Настройте списък с изображения (компонент TImageList в раздела „Палитра на компоненти Win32“) за TTreeview. Свойство StateImages, съдържащо изображенията за отметнати и непроверени състояния (и) за квадратчетата и / или радио бутоните.
  2. Обадете се на процедурата ToggleTreeViewCheckBoxes (вижте по-долу) в събитията OnClick и OnKeyDown на дървото. Процедурата ToggleTreeViewCheckBoxes променя StateIndex на избрания възел, за да отразява текущото проверено / непроверено състояние.

За да направите изгледа на дърво още по-професионален, трябва да проверите къде е щракнат даден възел, преди да включите изображението на състоянието: като превключите възела само когато щракнете върху действителното изображение, вашите потребители все още могат да изберат възела, без да го променят състояние.

Освен това, ако не искате вашите потребители да разширяват / сриват прегледа на дърво, извикайте процедурата FullExpand в събитието OnShow във формите и задайте AllowCollapse на false в събитието OnCollapsing на дърветата.

Ето изпълнението на процедурата ToggleTreeViewCheckBoxes:

процедура ToggleTreeViewCheckBoxes (
Възел: TTreeNode;
cUnChecked,
cChecked,
cRadioUnchecked,
cRadioChecked: цяло число);
Var
tmp: TTreeNode;
beginif Присвоен (възел) thenbeginif Възел. StateIndex = cUnChecked тогава
Възел. StateIndex: = cПроверено
ощеако Възел. StateIndex = проверено тогава
Възел. StateIndex: = cUnChecked
иначе ако Възел. StateIndex = cRadioUnChecked thenbegin
tmp: = Възел. майка;
ако не Присвоен (tmp) тогава
tmp: = TTreeView (Възел TreeView) .Items.getFirstNode
още
tmp: = tmp.getFirstChild;
докато Присвоен (tmp) dobeginif (ТМР. StateIndex в
[cRadioUnChecked, cRadioChecked]) тогава
ПТУ. StateIndex: = cRadioUnChecked;
tmp: = tmp.getNextSibling;
край;
Възел. StateIndex: = cRadioChecked;
край; // ако StateIndex = cRadioUnCheckedкрай; // ако е присвоен (възел)
край; (* ToggleTreeViewCheckBoxes *)

Както можете да видите от кода по-горе, процедурата започва от откриването на всякакви възли за отметка и просто ги включва или изключва. На следващо място, ако възелът е непроверен радио бутон, процедурата се премества към първия възел на текущото ниво, задава всички възли на това ниво, за да cRadioUncked (ако са cRadioUnChecked или cRadioChecked възли) и накрая превключва Node на cRadioChecked.

Забележете как се игнорират всички проверени радио бутони. Очевидно това е така, защото вече проверен радио бутон ще бъде включен без отметка, оставяйки възлите в неопределено състояние. Едва ли това, което бихте искали през повечето време.

Ето как да направите кода още по-професионален: в събитието OnClick на Treeview напишете следния код, за да превключите само квадратчетата за отметка, ако е щракнато изображението за състоянието (константи cFlatUnCheck, cFlatChecked и т.н. са дефинирани другаде като индекси в StateImages списък с изображения):

процедура TForm1.TreeView1Click (Подател: TObject);
Var
P: TPoint;
започвам
GetCursorPos (P);
P: = TreeView1.ScreenToClient (P);
ако (htOnStateIcon в
TreeView1.GetHitTestInfoAt (P.X, P.Y)) тогава
ToggleTreeViewCheckBoxes (
TreeView1.Selected,
cFlatUnCheck,
cFlatChecked,
cFlatRadioUnCheck,
cFlatRadioChecked);
край; (* TreeView1Click *)

Кодът получава текущата позиция на мишката, преобразува се в координати на преглед на дърво и проверява дали е щракнат върху StateIcon чрез извикване на функцията GetHitTestInfoAt. Ако беше, извиква се процедурата за включване.

Най-вече бихте очаквали интервала да превключва квадратчета за отметки или радио бутони, така че ето как да напишете събитието TreeView OnKeyDown, използвайки този стандарт:

процедура TForm1.TreeView1KeyDown (
Подател: TObject;
var Key: Word;
Shift: TShiftState);
beginif (Ключ = VK_SPACE) и
Присвоен (TreeView1.Selected) тогава
ToggleTreeViewCheckBoxes (
TreeView1.Selected,
cFlatUnCheck,
cFlatChecked,
cFlatRadioUnCheck,
cFlatRadioChecked);
край; (* TreeView1KeyDown *)

И накрая, ето как могат да изглеждат събитията OnShow на формата и OnChanging на Treeview, ако искате да предотвратите срутването на възлите на дървопрегледа:

процедура TForm1.FormCreate (подател: TObject);
започвам
TreeView1.FullExpand;
край; (* FormCreate *)
процедура TForm1.TreeView1Collapsing (
Подател: TObject;
Възел: TTreeNode;
Var AllowCollapse: Boolean);
започвам
AllowCollapse: = false;
край; (* TreeView1Collapsing *)

И накрая, за да проверите дали даден възел е проверен, просто извършете следното сравнение (например в ръководителя на събитията на OnClick на Button, например):

процедура TForm1.Button1Click (Подател: TObject);
Var
BoolResult: булев;
tn: TTreeNode;
beginif Присвоен (TreeView1.Selected) thenbegin
tn: = TreeView1.Избран;
BoolResult: = tn. StateIndex в
[cFlatChecked, cFlatRadioChecked];
Memo1.Text: = tn. Текст +
#13#10 +
'Избрано:' +
BoolToStr (BoolResult, True);
край;
край; (* Button1Click *)

Въпреки че този тип кодиране не може да се счита за критичен за мисията, той може да даде на приложенията ви по-професионален и гладък вид. Също така, използвайки разумните квадратчета и радио бутони, те могат да направят приложението ви по-лесно за използване. Те със сигурност ще изглеждат добре!

Това изображение по-долу е взето от тестово приложение с помощта на кода, описан в тази статия. Както можете да видите, можете свободно да смесвате възлите, които имат отметки или радио бутони, с тези, които нямат такива, въпреки че не трябва да смесвате „празни“ възли с „отметка"възли (погледнете радио бутоните в изображението), тъй като това прави много трудно да се разберат какви възли са свързани.

instagram story viewer