虚拟字符串树缓慢GetText方法在大量的节点

我对TVirtualStringTree组件还不是很有经验,所以也许我忽略了一些微不足道的东西。

我的应用程序将文件信息收集到记录(文件名,路径,大小)中,并将数据显示在虚拟字符串树中。

现在当有很多节点(200K +)时,我经历了一个沉重的减速,整个树基本上滞后。 我知道内存占用量非常大,只有记录数据,但我发现滞后是由VST的OnGetText方法引起的。 因此,如果方法读取实际数据或将CellText设置为静态字符串(例如CellText:='Test'),则无关紧要,因为减速是显着的。 如果我没有设置CellText就退出OnGetText,它可以正常工作 - 即使在我的树中有多达1,000,000个节点。 此外,如果我折叠Tree(FullCollapse)隐藏90%的节点,则OnGetText表现良好,或者至少好得多。

据我了解,OnGetText只能用于实际可见的屏幕节点,因此我不明白为什么这是树中有大量节点的问题。

任何人有任何提示让我指出我的方向?

编辑:

Delphi版本: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;

我注意到,扩展/崩溃和重新扩展似乎改善了这种情况,但我无法说出为什么这可能会产生任何影响。


如果您的任何列都是自动调整大小的,那么控件需要知道所有节点值的宽度以确定最大值。


奇怪的是,我认为这是VST的整个设计,只为活动视图中的节点加载cellnodes,而不是整个树。 你确定它不是代码中的其他因素,你没有显示,比如为每个节点做一个文件存在的东西吗?


问题解决了。 事实证明,删除节点时可能会出现复杂情况。 不是删除父节点的所有子节点,只有父节点已被删除。 我预计子节点也会自动删除,但是当我更改代码以首先删除子节点时,父节点的滞后消失了。 现在我可以无延迟地将一百万个文件名加载到树中。

链接地址: http://www.djcxy.com/p/5963.html

上一篇: Virtual String Tree Slow GetText Method At Large Amount Of Nodes

下一篇: Fast scrolling in Delphi's Virtual Treeview