Search code examples
delphidelphi-7virtualtreeviewtvirtualstringtree

Edit a root node celltext in VirtualTreeView


I would like to change the cell text of an existing virtual (root) node. I can change the data but I have to refresh the whole TreeView so the GetText get's fired again. Is there an easier way or a possible way to refresh only 1 root node and not the whole tree?

Thank you for your help.


Solution

  • In the following code I've tried to simulate your node updating event. Here is represented by the button click Button1Click event. Here if you click the button, the value in the data record will be increased and the node will be forced to repaint (what will trigger the OnGetText event, where you will have this new increased value in that record ready to get). In your real code you need to do something like this:

    • find the node you want to update (I found the TopNode :-)
    • update the data record of that node (the Count value is incremented in my case)
    • call the InvalidateNode for that node (what will trigger the virtual event chain of some events, but the OnGetText will be among them)

    type
      PTreeData = ^TTreeData;
      TTreeData = record
        Title: string;
        Count: Integer;
      end;
    
    procedure TForm1.FormCreate(Sender: TObject);
    var
      TreeData: PTreeData;
      TreeNode: PVirtualNode;
    begin
      // this is just for memory leaks report
      ReportMemoryLeaksOnShutdown := True;
      // initialize data size for our data record
      VirtualTree.NodeDataSize := SizeOf(TTreeData);
      // add one node and store it to the TreeNode variable
      TreeNode := VirtualTree.AddChild(nil);
      // get the pointer to just created node data record
      TreeData := VirtualTree.GetNodeData(TreeNode);
      // and assign some values to that data record
      TreeData.Title := 'Count: ';
      TreeData.Count := 0;
    end;
    
    procedure TForm1.Button1Click(Sender: TObject);
    var
      TreeData: PTreeData;
      TreeNode: PVirtualNode;
    begin
      // now I take the the top node just as an example
      TreeNode := VirtualTree.TopNode;
      // get the pointer to its data record
      TreeData := VirtualTree.GetNodeData(TreeNode);
      // increase the value in data record for this node
      TreeData.Count := TreeData.Count + 1;
      // and force the node to repaint, what will except
      // other events trigger also the OnGetText one
      VirtualTree.InvalidateNode(TreeNode);
    end;
    
    procedure TForm1.VirtualTreeGetText(Sender: TBaseVirtualTree;
      Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
      var CellText: string);
    var
      TreeData: PTreeData;
    begin
      // here I'll get the pointer to data of the currently refreshed cell's node
      TreeData := VirtualTree.GetNodeData(Node);
      // and return the caption of the cell
      CellText := TreeData.Title + IntToStr(TreeData.Count);
    end;
    
    procedure TForm1.VirtualTreeFreeNode(Sender: TBaseVirtualTree;
      Node: PVirtualNode);
    var
      TreeData: PTreeData;
    begin
      // this is here because of VT memory leaks, so get the pointer to data
      TreeData := Sender.GetNodeData(Node);
      // and finalize them
      Finalize(TreeData^);
    end;