Virtual String Tree Slow GetText Method At Large Amount Of Nodes
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 (eg 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.
如果您的任何列都是自动调整大小的,那么控件需要知道所有节点值的宽度以确定最大值。
Strange, I thought it was the whole design of VST to only load cellnodes for the nodes in the active view, not the entire tree. Are you sure it isn't some other factor in the code that you don't show, like doing a fileexists or so for every node?
Problem solved. It turns out, there might have been a complication while deleting nodes. Instead of deleting all children of a parent node, only the parent node has been removed. I expected the childnodes to be removed automatically as well, but when I changed the code to first delete children then the parent node, the lagging vanished. Now I can load a million file names to the tree without lag.
链接地址: http://www.djcxy.com/p/5964.html