我对 TVirtualStringTree 组件还不是很有经验,因此也许我忽略了一些微不足道的事情。
我的应用程序将文件信息收集到记录(文件名、路径、大小)中,并在虚拟字符串树中显示数据。
现在,当有很多节点(200K+)时,我经历了严重的减速,整个树基本上都滞后了。我知道仅记录数据占用的内存就很大,但我发现延迟是由 VST 的 OnGetText 方法引起的。因此,该方法是否读取实际数据或将 CellText 设置为静态字符串(例如 CellText := 'Test';)并不重要,减速很重要。如果我在不设置 CellText 的情况下退出 OnGetText,它可以正常工作 - 即使我的树中有多达 1,000,000 个节点。此外,如果我折叠树(FullCollapse)以这种方式隐藏 90% 的节点,OnGetText 的行为也可以,或者至少要好得多。
据我了解,仅在实际可见的屏幕节点上调用 OnGetText,因此我不明白为什么树中有大量节点会出现这样的问题。
有人有任何提示让我指出一个方向吗?
编辑:
德尔福版本:D2010 VST 版本:4.8.6
我最简单的测试形式的代码基本上如下:
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;
如果我设置 CellText,它会滞后,如果我退出,它不会。奇怪的是,我越往下滚动,情况就越糟。
这是分配为 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;
我注意到,扩展/折叠和重新扩展似乎以某种方式改善了这种情况,但我无法说出为什么这实际上会产生任何影响。