TreeView с флажками и радиокнопками

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

Узел дерева с флажком или переключателем?

Delphi TTreeview изначально не поддерживает флажки, но базовый элемент управления WC_TREEVIEW поддерживает. Вы можете добавить флажки к в виде дерева переопределив процедуру CreateParams в TTreeView, указав стиль TVS_CHECKBOXES для элемента управления. В результате все узлы в древовидной структуре будут установлены флажки. Кроме того, свойство StateImages больше нельзя использовать, потому что WC_TREEVIEW использует этот список изображений для реализации флажков. Если вы хотите установить флажки, вы должны сделать это с помощью Отправить сообщение или TreeView_SetItem / TreeView_GetItem макросы из CommCtrl.pas. WC_TREEVIEW поддерживает только флажки, а не переключатели.

Подход, который вы обнаружите в этой статье, гораздо более гибкий: у вас могут быть флажки и переключатели, смешанные с другими узлами, без изменения TTreeview или создания нового

instagram viewer
учебный класс из этого, чтобы сделать эту работу. Кроме того, вы сами решаете, какие изображения использовать для флажков / радиокнопок, просто добавив соответствующие изображения в список изображений 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: целое число);
вар
tmp: TTreeNode;
beginif Назначено (Узел) thenbeginif Узел. StateIndex = cUnChecked тогда
Узел. StateIndex: = cChecked
ещеесли Узел. StateIndex = cChecked тогда
Узел. StateIndex: = cUnChecked
иначе если Узел. StateIndex = cRadioUnChecked thenbegin
TMP: = узел. родитель;
если не Назначено (тпм) тогда
tmp: = TTreeView (Node. TreeView) .Items.getFirstNode
еще
tmp: = tmp.getFirstChild;
пока Назначено (тпм) dobeginif (TMP. StateIndex в
[cRadioUnChecked, cRadioChecked]) тогда
TMP. StateIndex: = cRadioUnChecked;
tmp: = tmp.getNextSibling;
конец;
Узел. StateIndex: = cRadioChecked;
конец; // if StateIndex = cRadioUnCheckedконец; // если назначено (узел)
конец; (* ToggleTreeViewCheckBoxes *)

Как видно из приведенного выше кода, процедура начинается с поиска любых узлов-флажков и их включения или выключения. Далее, если узел является неконтролируемой радиокнопкой, процедура переходит к первому узлу на текущем уровне, устанавливает все узлы на этом уровне к cRadioUnchecked (если они являются узлами cRadioUnChecked или cRadioChecked) и, наконец, переключает узел на cRadioChecked.

Обратите внимание, что любые уже проверенные переключатели игнорируются. Очевидно, это связано с тем, что уже установленный переключатель будет переключаться в непроверенное состояние, оставляя узлы в неопределенном состоянии. Вряд ли вы хотели бы большую часть времени.

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

процедура TForm1.TreeView1Click (Отправитель: TObject);
вар
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, если вы хотите предотвратить свертывание узлов TreeView:

процедура TForm1.FormCreate (Отправитель: TObject);
начать
TreeView1.FullExpand;
конец; (* FormCreate *)
процедура TForm1.TreeView1Collapsing (
Отправитель: TObject;
Узел: TTreeNode;
вар AllowCollapse: Boolean);
начать
AllowCollapse: = false;
конец; (* TreeView1Collapsing *)

Наконец, чтобы проверить, проверен ли узел, просто выполните следующее сравнение (например, в обработчике события OnClick для Button):

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

Хотя этот тип кодирования нельзя считать критически важным, он может придать вашим приложениям более профессиональный и плавный вид. Кроме того, разумно используя флажки и переключатели, они могут упростить использование вашего приложения. Они обязательно будут хорошо выглядеть!

Это изображение ниже было взято из тестового приложения с использованием кода, описанного в этой статье. Как вы можете видеть, вы можете свободно смешивать узлы с флажками или переключателями с теми, у которых их нет, хотя вам не следует смешивать «пустые» узлы сфлажок"узлы (взгляните на переключатели на изображении), так как это очень трудно увидеть, какие узлы связаны между собой.

instagram story viewer