TreeView avec cases à cocher et boutons radio

Le composant TTreeView Delphi (situé sur l'onglet de la palette de composants "Win32") représente une fenêtre qui affiche un liste hiérarchique des éléments, tels que les en-têtes d'un document, les entrées d'un index ou les fichiers et répertoires un disque.

Nœud d'arbre avec case à cocher ou bouton radio?

TTreeview de Delphi ne prend pas en charge nativement les cases à cocher, mais le contrôle WC_TREEVIEW sous-jacent le fait. Vous pouvez ajouter des cases à cocher au treeview en remplaçant la procédure CreateParams de TTreeView, en spécifiant le style TVS_CHECKBOXES pour le contrôle. Le résultat est que tous noeuds dans l'arborescence, des cases à cocher leur seront attachées. De plus, la propriété StateImages ne peut plus être utilisée car WC_TREEVIEW utilise cette liste d'images en interne pour implémenter des cases à cocher. Si vous souhaitez basculer les cases à cocher, vous devrez le faire en utilisant Envoyer le message ou la Macros TreeView_SetItem / TreeView_GetItem de CommCtrl.pas. WC_TREEVIEW ne prend en charge que les cases à cocher, pas les boutons radio.

instagram viewer

L'approche que vous allez découvrir dans cet article est beaucoup plus flexible: vous pouvez avoir des cases à cocher et boutons radio mélangés avec d'autres nœuds comme vous le souhaitez sans changer la TTreeview ou créer un nouveau classe de lui pour faire ce travail. De plus, vous décidez vous-même des images à utiliser pour les cases à cocher / boutons radio simplement en ajoutant les images appropriées à la liste d'images StateImages.

Ajouter une case à cocher ou un bouton radio

Contrairement à ce que vous pourriez croire, c'est assez simple à réaliser en Delphes. Voici les étapes pour le faire fonctionner:

  1. Configurez une liste d'images (composant TImageList sur l'onglet de la palette de composants "Win32") pour TTreeview. Propriété StateImages contenant les images des états cochés et non cochés des cases à cocher et / ou des boutons radio.
  2. Appelez la procédure ToggleTreeViewCheckBoxes (voir ci-dessous) dans les événements OnClick et OnKeyDown de l'arborescence. La procédure ToggleTreeViewCheckBoxes modifie le StateIndex du nœud sélectionné pour refléter l'état coché / décoché actuel.

Pour rendre votre arborescence encore plus professionnelle, vous devez vérifier où un nœud est cliqué avant de basculer les images d'état: en ne basculant le nœud que lorsque l'image réelle est cliquée, vos utilisateurs peuvent toujours sélectionner le nœud sans changer son Etat.

En outre, si vous ne souhaitez pas que vos utilisateurs développent / réduisent l'arborescence, appelez la procédure FullExpand dans l'événement OnShow de formulaires et définissez AllowCollapse sur false dans l'événement OnCollapsing de l'arborescence.

Voici l'implémentation de la procédure ToggleTreeViewCheckBoxes:

procédure ToggleTreeViewCheckBoxes (
Node: TTreeNode;
cUnChecked,
cChecked,
cRadioUnchecked,
cRadioChecked: entier);
var
tmp: TTreeNode;
début Attribué (nœud) thenbeginif Nœud. StateIndex = cUnChecked ensuite
Nœud. StateIndex: = cChecked
autresi Nœud. StateIndex = cChecked ensuite
Nœud. StateIndex: = cUnChecked
sinon si Nœud. StateIndex = cRadioUnChecked puis commencer
tmp: = Noeud. Parent;
si non Attribué (tmp) ensuite
tmp: = TTreeView (Node. TreeView) .Items.getFirstNode
autre
tmp: = tmp.getFirstChild;
tandis que Attribué (tmp) dobeginif (tmp. StateIndex dans
[cRadioUnChecked, cRadioChecked]) ensuite
tmp. StateIndex: = cRadioUnChecked;
tmp: = tmp.getNextSibling;
fin;
Nœud. StateIndex: = cRadioChecked;
fin; // si StateIndex = cRadioUnCheckedfin; // si assigné (nœud)
fin; (* ToggleTreeViewCheckBoxes *)

Comme vous pouvez le voir dans le code ci-dessus, la procédure commence par trouver tous les nœuds de case à cocher et simplement les activer ou désactiver. Ensuite, si le nœud est un bouton radio non coché, la procédure se déplace vers le premier nœud du niveau actuel, définit tous les nœuds à ce niveau vers cRadioUnchecked (s’il s’agit de nœuds cRadioUnChecked ou cRadioChecked) et enfin fait basculer Node vers cRadioChecked.

Remarquez comment les boutons radio déjà cochés sont ignorés. Évidemment, cela est dû au fait qu'un bouton radio déjà coché serait basculé sur non coché, laissant les nœuds dans un état non défini. À peine ce que vous voudriez la plupart du temps.

Voici comment rendre le code encore plus professionnel: dans l'événement OnClick de l'arborescence, écrivez le code suivant pour basculer uniquement le cases à cocher si l'image d'état a été cliquée (les constantes cFlatUnCheck, cFlatChecked etc. sont définies ailleurs comme des index dans les StateImages liste d'images):

procédure TForm1.TreeView1Click (expéditeur: TObject);
var
P: TPoint;
commencer
GetCursorPos (P);
P: = TreeView1.ScreenToClient (P);
si (htOnStateIcon dans
TreeView1.GetHitTestInfoAt (P.X, P.Y)) ensuite
ToggleTreeViewCheckBoxes (
TreeView1.Selected,
cFlatUnCheck,
cFlatChecked,
cFlatRadioUnCheck,
cFlatRadioChecked);
fin; (* TreeView1Click *)

Le code obtient la position actuelle de la souris, se convertit en coordonnées arborescentes et vérifie si StateIcon a été cliqué en appelant la fonction GetHitTestInfoAt. Si tel était le cas, la procédure de basculement est appelée.

Généralement, vous vous attendez à ce que la barre d'espace bascule les cases à cocher ou les boutons radio, alors voici comment écrire l'événement TreeView OnKeyDown en utilisant cette norme:

procédure TForm1.TreeView1KeyDown (
Expéditeur: TObject;
var Key: Word;
Shift: TShiftState);
début (Clé = VK_SPACE) et
Attribué (TreeView1.Selected) ensuite
ToggleTreeViewCheckBoxes (
TreeView1.Selected,
cFlatUnCheck,
cFlatChecked,
cFlatRadioUnCheck,
cFlatRadioChecked);
fin; (* TreeView1KeyDown *)

Enfin, voici à quoi pourraient ressembler les événements OnShow du formulaire et OnChanging du Treeview si vous vouliez empêcher l'effondrement des nœuds du treeview:

procédure TForm1.FormCreate (expéditeur: TObject);
commencer
TreeView1.FullExpand;
fin; (* FormCreate *)
procédure TForm1.TreeView1Collapsing (
Expéditeur: TObject;
Node: TTreeNode;
var AllowCollapse: Boolean);
commencer
AllowCollapse: = false;
fin; (* TreeView1Collapsing *)

Enfin, pour vérifier si un nœud est vérifié, il vous suffit de faire la comparaison suivante (dans le gestionnaire d'événements OnClick d'un bouton, par exemple):

procédure TForm1.Button1Click (expéditeur: TObject);
var
BoolResult: booléen;
tn: TTreeNode;
début Attribué (TreeView1.Selected) puis commencer
tn: = TreeView1.Selected;
BoolResult: = tn. StateIndex dans
[cFlatChecked, cFlatRadioChecked];
Memo1.Text: = tn. Texte +
#13#10 +
'Sélectionné:' +
BoolToStr (BoolResult, True);
fin;
fin; (* Button1Click *)

Bien que ce type de codage ne puisse pas être considéré comme essentiel à la mission, il peut donner à vos applications un aspect plus professionnel et plus fluide. De plus, en utilisant judicieusement les cases à cocher et les boutons radio, ils peuvent rendre votre application plus facile à utiliser. Ils auront certainement fière allure!

Cette image ci-dessous provient d'une application de test utilisant le code décrit dans cet article. Comme vous pouvez le voir, vous pouvez mélanger librement des nœuds ayant des cases à cocher ou des boutons radio avec ceux qui n'en ont pas, bien que vous ne deviez pas mélanger des nœuds "vides" avec "case à cocher"nœuds (regardez les boutons radio dans l'image) car cela rend très difficile de voir quels nœuds sont liés.