I am not yet very experienced with the TVirtualStringTree component, therefore maybe I overlooked something trivial.
My app gathers File Information into a record (FileName, Path, Size) and displays the data in a Virtual String Tree.
Now when there are lots of Nodes (200K+) I experience a heavy slow down, the whole Tree basically lags. I am aware that the memory footprint is quite large with just the record data alone, but I found out that the lag is caused by the OnGetText method of the VST. Hereby it doesn't matter if the method reads actual data or sets the CellText to an static string (e.g. CellText := 'Test';) the slow down is significant. If I exit OnGetText without setting CellText, it works fine - even with as much as 1,000,000 Nodes in my Tree. Also, If I collapse the Tree (FullCollapse) hiding this way 90% of my Nodes, OnGetText behaves ok as well or at least much better.
As far as I understand it, the OnGetText is only called for actually visible On Screen Nodes, therefore I don't get why this is such an issue with large amounts of Nodes in the Tree.
Anybody has any hints for me to point me in a direction?
EDIT:
Delphi Version: D2010 VST Version: 4.8.6
My code in its simplest test form is basically as follows:
var
SkipGetText : boolean;
procedure TXForm.VSTGetText(Sender: TBaseVirtualTree;
Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
begin
if SkipGetText then exit;
CellText := 'TEST';
// actual code commented out to reduce complications
end;
If I set CellText, it lags, if I exit, it doesn't. Strange enough, it gets worse the further I scroll down.
Here's what's assigned as NodeData:
type
PVSData = ^Fi;
Fi = Packed Record
Name, Dir, Ext: String;
Size: Int64;
end;
procedure TXForm.AddFile( const RootFolder:string; const SR: TSearchRec );
var
FileInfo: PVSData;
FileSize: Int64;
Node: PVirtualNode;
begin
Node := VST.AddChild(nil);
INC(AllFiles);
FileInfo := VST.GetNodeData(Node);
FileInfo^.Name := SR.Name;
FileInfo^.Dir := RootFolder;
Int64Rec(FileSize).Hi := SR.FindData.nFileSizeHigh;
Int64Rec(FileSize).Lo := SR.FindData.nFileSizeLow;
FileInfo^.Size := FileSize;
end;
procedure TXForm.VSTPaintText(Sender: TBaseVirtualTree;
const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType);
begin
if SkipPaintText then exit;
case ListView.GetNodeLevel(Node) of
0: TargetCanvas.Font.Color := Color1;
else TargetCanvas.Font.Color := Color2;
end;
end;
procedure TXForm.VSTBeforeCellPaint(Sender: TBaseVirtualTree;
TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
CellPaintMode: TVTCellPaintMode; CellRect: TRect; var ContentRect: TRect);
begin
case ListView.GetNodeLevel(Node) of
0: TargetCanvas.Font.Color := Color1;
else TargetCanvas.Font.Color := Color2;
end;
end;
I noticed, that expanding / collapsing and re-expanding somehow seems to improve the situation, but it's beyond me to tell why this could actually have any impact.