Я еще не очень разбираюсь в компоненте TVirtualStringTree, поэтому, возможно, я упустил что-то тривиальное.
Мое приложение собирает информацию о файле в запись (FileName, Path, Size) и отображает данные в виртуальном дереве строк.
Теперь, когда есть много узлов (200K +), я испытываю сильное замедление, все дерево в основном отстает. Мне известно, что объем памяти достаточно велик только для одних только данных записи, но я обнаружил, что задержка вызвана методом OnGetText VST.
При этом не имеет значения, читает ли метод фактические данные или устанавливает для CellText статическую строку (например, CellText: = 'Test';) замедление является значительным.
Если я выйду из OnGetText без настройки CellText, он будет работать нормально - даже если в моем дереве будет 1000000 узлов.
Кроме того, если я сверну дерево (FullCollapse), скрывающее таким образом 90% моих узлов, OnGetText также будет работать нормально или, по крайней мере, намного лучше.
Насколько я понимаю, OnGetText вызывается только для реально видимых экранных узлов, поэтому я не понимаю, почему это такая проблема с большим количеством узлов в дереве.
У кого-нибудь есть намеки на то, чтобы я указывал мне направление?
EDIT:
Delphi Version: 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;
Я заметил, что расширение / свертывание и повторное расширение каким-то образом улучшают ситуацию, но я не могу сказать, почему это может оказать какое-то влияние.