====== Virtual Tree View ====== ===== Fonctionnement ===== Les TVirtualTrees contiennent un ensemble de **Node** (de type PVirtualNode). Chaque **Node** contient un membre **Data** TVirtualNode.Data (''Data: record end;'') Ce **Data** contient la donnée a gérer pour ce nœud.\\ En general la donnée est un record qui peut contenir n'importe quoi , par exemple... TTreeData = record Text: String; URL: string[255]; ImageIndex: integer; end; PTreeData = ^TTreeData; On déclare aussi un type pointer vers TTreeData (''PTreeData'') qui nous sera utile plus tard... ==== Initialisation ==== Il faut initialiser le TVirtualTree en lui disant la taille des noeuds grace a **NodeDataSize** procedure TForm1.FormCreate(Sender: TObject); begin VSTMain.NodeDataSize := SizeOf(TTreeData); end; Notez bien que c'est SizeOf(**T**TreeData) et **NON** SizeOf(**P**TreeData) \\ Sinon ça bug dans tous les sens... ==== Ajout d'un Noeud ==== Pour ajouter un noeud : procedure TForm1.FormCreate(Sender: TObject); var pNode: PVirtualNode; pData: PTreeData; begin VSTMain.BeginUpdate; pNode := VSTMain.AddChild(nil); pData := VSTMain.GetNodeData(pNode); pData^.Text := 'root'; VSTMain.EndUpdate; end; ==== Affichage d'un Noeud ==== === Affichage du texte du noeud === Lors du dessin du composant, le TVirtualTree se sert de l'evenement ''OnGetText'' pour recuperer le texte a afficher. procedure TForm1.VSTMainGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: String); var pData: PTreeData; begin pData := VST.GetNodeData(Node); case Column of 0: CellText:= IntToStr(pData^.id); 1: CellText:= IntToStr(pData^.Flags); 2: CellText:= IntToStr(pData^.Current); 3: CellText:= IntToStr(pData^.Worst); end; end; === Affichage des images/icones === On peut mettre deux images avant le texte du noeud. - L'image "Normale", dont le ''TImageList'' sera stocké dans la property ''images'' et la largeur définie dans la propety ''imagesWidth''. - L'image "State", dont le ''TImageList'' sera stocké dans la property ''StateImages'' et la largeur définie dans la propety ''StateImagesWidth''. Lorsque le VST veux récupérer l'index de l'image à afficher, le paramètre ''Kind'' contient l'information du type d'image qu'il souhaite: * ''ikNormal'' : L'image "Normale" * ''ikSelected'' : L'image "Normale" quand la ligne est séléctionnée * ''ikState'' : L'image "State" * ''ikOverlay'' : ..... Le paramètre ''Column'' contient l'index de la colonne pour laquelle il veut l'ImageIndex. procedure TFrameVSTDisks.VSTGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: boolean; var ImageIndex: integer); var pData: PTreeData; begin pData := VST.GetNodeData(Node); ImageIndex := -1; case Column of C_COL_DEVICE: case Kind of ikState: ImageIndex := -1; ikNormal,ikSelected: ImageIndex := pData^.Img; end; C_COL_SMART: case Kind of ikState: ImageIndex := -1; ikNormal,ikSelected: ImageIndex := pData^.SmartImg; end; end; end; ==== Expanded ==== === Un noeud === { Expand un Node } VSTMain.Expanded[FRootNode]:=true; { Savoir si un Node est expanded } ExpBool:=VSTMain.Expanded[FRootNode]; === Tout === VST.FullExpand; VST.FullCollapse; ==== Tri ==== Le tri d'une colonne peut etre déclenché par : * Click sur l’entête de la colonne. Dans ce cas l'option ''Header/Options/hoHeaderClickAutoSort'' doit etre à ''True''. * Appel a la procédure Sort : ''VST.Sort(Node,Column,Sens);'' Pour comparer les nœuds le VST utilise l'event ''OnCompareNodes'' { Exemple simpliste sans prise en compte de l'index de la column } procedure TFrameVSTDisks.VSTCompareNodes(Sender: TBaseVirtualTree; Node1, Node2: PVirtualNode; Column: TColumnIndex; var Result: Integer); var pD1,pD2: PTreeData; begin pD1:= VST.GetNodeData(Node1); pD2:= VST.GetNodeData(Node2); Result:=0; // Les noeud sont égaux if pD1^.Index>pD2^.Index then Result:=1; // node1>node2 -> Result= 1 if pD1^.Index Result= -1 end; Ressources pour le tri : * [[https://documentation.help/VirtualTreeview/TBaseVirtualTree_Sort@PVirtualNode@TColumnIndex@TSortDirection@Boolean.html|Procédure SORT @Doc Officielle]] * [[https://documentation.help/VirtualTreeview/TBaseVirtualTree_OnCompareNodes.html|OnCompareNode @DocOfficielle]] ==== Modifications ==== === BeginUpdate / EndUpdate === Lorsque l'on met a jour un VST, il est bon pour l'affichage et la rapidité d'entourer ces mises a jour par un ''BeginUpdate'' et un ''EndUpdate''. VST.BeginUpdate; try ... finally VST.EndUpdate; end; ==== Déstruction du VST ==== === OnFreeNode === J'ai eu un pb de MemoryLeak avec un VST que j'ai résolu de la façon suivante procedure TForm1.VSTMainFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode); var Data: PTreeData; begin Data := VSTMain.GetNodeData(Node); Finalize(Data^); end; On en parle ici :[[https://www.remkoweijnen.nl/blog/2010/06/09/memory-leaks-when-using-virtual-treeview-component/]] Plus d'infos sur ''Finalize()'' : [[https://www.freepascal.org/docs-html/rtl/system/finalize.html]] On voit aussi... procedure TForm1.VSTMainFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode); var Data: PTreeData; begin Data := VSTMain.GetNodeData(Node); Data^.Text:=''; Data^.URL:=''; end; ===== Sources et Ressources ===== * [[https://jlelong.developpez.com/articles/virtualtreeview/]] * [[https://documentation.help/VirtualTreeview/$Main.html]] * [[https://wiki.freepascal.org/VirtualTreeview_Example_for_Lazarus/fr]]