Le composant Delphi TTreeView (situé sur l'onglet de la palette de composants "Win32") représente une fenêtre qui affiche une liste hiérarchique d'éléments, tels que les en-têtes d'un document, les entrées d'un index ou les fichiers et répertoires d'un disque..
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 à l'arborescence 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 les nœuds de l'arborescence auront des cases à cocher 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.
L'approche que vous devez découvrir dans cet article est beaucoup plus flexible: vous pouvez avoir des cases à cocher et des boutons radio mélangés avec d'autres nœuds comme vous le souhaitez sans changer la TTreeview ou créer une nouvelle classe à partir de cela pour que cela fonctionne. En outre, 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.
Contrairement à ce que vous pourriez croire, c'est assez simple à réaliser dans Delphi. Voici les étapes pour le faire fonctionner:
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 état.
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,
cVérifié,
cRadioUnchecked,
cRadioChecked: entier);
var
tmp: TTreeNode;
beginif Attribué (nœud) thenbeginif Node.StateIndex = cUnChecked ensuite
Node.StateIndex: = cChecked
autre si Node.StateIndex = cChecked ensuite
Node.StateIndex: = cUnChecked
sinon si Node.StateIndex = cRadioUnChecked puis commencer
tmp: = Node.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;
Node.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 passe au premier nœud du niveau actuel, définit tous les nœuds de ce niveau sur cRadioUnchecked (s'ils sont des nœuds cRadioUnChecked ou cRadioChecked) et enfin bascule Node sur 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 indé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 ne basculer les cases à cocher que si l'image d'état a été cliquée (les constantes cFlatUnCheck, cFlatChecked, etc. sont définies ailleurs en tant qu'index dans la liste d'images StateImages) :
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);
beginif (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;
beginif Attribué (TreeView1.Selected) puis commencer
tn: = TreeView1.Selected;
BoolResult: = tn.StateIndex dans
[cFlatChecked, cFlatRadioChecked];
Memo1.Text: = tn.Text +
# 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 des nœuds "case à cocher" (jetez un œil aux boutons radio dans l'image) car cela rend très difficile de voir quels nœuds sont liés.