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…
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;
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;
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;
On peut mettre deux images avant le texte du noeud.
TImageList
sera stocké dans la property images
et la largeur définie dans la propety imagesWidth
.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éeikState
: 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;
{ Expand un Node } VSTMain.Expanded[FRootNode]:=true; { Savoir si un Node est expanded } ExpBool:=VSTMain.Expanded[FRootNode];
VST.FullExpand; VST.FullCollapse;
Le tri d'une colonne peut etre déclenché par :
Header/Options/hoHeaderClickAutoSort
doit etre à True
.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<pD2^.Index then Result:=-1; // node1<node2 -> Result= -1 end;
Ressources pour le tri :
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;
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;