Я уже некоторое время использую virtualstringtree.Я использую его для двух разных вещей: во-первых, как обычное дерево для выбора, отображения данных, а во-вторых, как сетку для отображения выходных данных операторов SQL.
Все мои данные, загруженные в деревья, взяты из базы данных.В примере с деревом у меня есть поле parentId для различения иерархии, а в примерах с сеткой я просто использую оператор SQL с настраиваемой записью для каждого дерева (которая уникальна).
Мои вопросы относятся кпредпочтительный / лучший способ заселить дерево.Я прочитал из документации VST, что вы должны использовать событие onInitNode вместе с rootnodecount.Однако я обнаружил, что использование метода AddChild () очень похоже, хотя это и не поощряется.
Позвольте мне показать несколько (упрощенных) примеров:
1.Heirarchy
type PData = ^rData;
rData = packed record
ID : Integer;
ParentID : Integer;
Text : WideString;
end;
procedure Loadtree;
var Node : PVirtualNode;
Data : PData;
begin
Q1 := TQuery.Create(Self);
try
Q1.SQL.Add('SELECT * FROM Table');
Q1.Open;
Q1.Filter := 'ParentID = -1'; //to get the root nodes
Q1.Filtered := True;
while not Q1.Eof do
begin
Node := VST.AddChild(nil);
Data := VST.GetNodeData(Node);
Data.ID := Q1.Fields[fldID].AsInteger;
Data.ParentID := Q1.Fields[fldParentID].AsInteger;
Data.Text := Q1.Fields[fldText].AsString;
//now filter the query again to get the children of this node
PopulateChildren(Data.ParentID,Node); //add children to this node and do it recursively
Q1.Next;
end;
finally
Q1.free;
end;
end;
2.Сетка
procedure LoadGrid;
var Node : PVirtualNode;
Data : PData;
begin
Q1 := TQuery.Create(self);
try
Q1.SQL.Add('SELECT * FROM Table');
Q1.Open;
while not Q1.eof do
begin
Node := VST.AddChild(nil);
Data.ID := Q1.Fields[fldID].AsInteger;
Data.Text := Q1.Fields[fldText].AsString;
Q1.Next;
end;
finally
Q1.Free;
end;
end;
Итак, по сути я обхожу методы / свойства RootNodeCount и OnInitNode и использую старомодный способ добавления узлов в дерево.Вроде нормально работает.Обратите внимание, что в примере я создаю и уничтожаю свои запросы во время выполнения.
Причина, по которой я начал использовать дерево таким образом, заключается в том, что я мог загрузить все данные в дереве один раз, а затем освободить TQuery после того, как закончилиспользуй это.Я думал, что независимо от того, чтобы сохранить / создать TQuery, мне все равно нужно будет использовать мою запись rData для хранения данных, а значит, использовать больше памяти, если я не уничтожу TQuery.В настоящее время мое приложение использует около 250 МБ при полной загрузке и может увеличиваться, когда я запускаю отчеты SQL и отображаю их в VST.Я видел, что он использует около 1 ГБ оперативной памяти, когда я запустил отчет SQL с 20000+ узлов и более 50 столбцов.Что я хотел бы знать, если способ, которым я использую VST, неверен в отношении минимизации использования памяти?
Будет ли лучше создать запрос на время существования дерева и использовать событие onInitNode?Так что, когда данные запрашиваются деревом, они извлекают их из TQuery, используя событие onInitNode / OnInitChildren (то есть чисто виртуальную парадигму дерева)?Таким образом, мне нужно будет поддерживать TQuery в течение всей формы.Будет ли какая-либо польза от памяти / производительность при использовании этого способа?
В вышеупомянутых ситуациях я могу видеть, что разница для примера сетки будет намного меньше (если есть), чем иерархия - из-затот факт, что все узлы должны быть инициализированы при заполнении.