我还没有非常丰富的TVirtualStringTree组件经验,因此也许我忽略了一些微不足道的东西。德尔福 - 虚拟字符串树缓慢GetText方法在大量的节点
我的应用程序将文件信息收集到记录(文件名,路径,大小)并显示在虚拟字符串树中的数据。
现在,当有很多节点(200K +)时,我经历了一个沉重的减速,整个树基本上滞后。我知道内存占用量非常大,只有记录数据,但我发现滞后是由VST的OnGetText方法引起的。 因此,如果方法读取实际数据或将CellText设置为静态字符串(例如,CellText:='Test';),则减速效果显着无关紧要。 如果我在不设置CellText的情况下退出OnGetText,它可以正常工作 - 即使在我的树中也有多达1,000,000个节点。 另外,如果我折叠Tree(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;
我注意到,那展开/折叠和再膨胀在某种程度上似乎改善这种情况,但它超出了我知道为什么这样做可能会造成任何影响。
如果您显示您的代码,至少您在OnGetText处理程序中拥有的代码,您将得到更好的答案。顺便说一句,我只有经历了缓慢的起伏,当我在一个方法中做了一些“愚蠢的事情”时,几乎每个鼠标移动都会被调用... – 2010-07-28 17:09:58
Hi BlackOut!欢迎来到StackOverflow。这是一个很好的第一个问题。我对VirtualStringTree了解不多,因此我不会尝试发布真正的答案,但听起来您的性能随着开放节点数量的增加呈线性下降。这使得看起来像设置CellText必须扫描树的所有节点出于某种原因。尝试查看代码并查看在更改CellText时是否可以找到某种线性搜索。 – 2010-07-28 17:14:41
我的代码非常基本,因为我已经删除了每个可能使事情复杂化以便进行调试的部分。 与此同时,我想我可能会看到一些东西,因为它似乎一旦我再次崩溃并展开树,它就可以正常工作。我会给它更多的测试和明天更新我的文章,或者如果我碰巧找出什么是负责任的,请添加一个答案。 – BlackOut 2010-07-28 23:54:07