Note that there are some explanatory texts on larger screens.

plurals
  1. POVirtualStringTree Correct/recommended use
    text
    copied!<p>I have been using virtualstringtree for a while now. I use it for two different things, first a s a normal tree for selecting ,displaying data and secondly as a grid to show outputs from SQL statements.</p> <p>All my data loaded in to the trees is from a database. For the tree example, i have a parentId field to distinguish the heirarchy, and for the grid examples i simply use an SQL statement with a customized record for each tree (that is unique).</p> <p>My questions relates to the preferred/best way to populate the tree. I have read from the VST docs that you should use the onInitNode event along with rootnodecount. However i have found that using the AddChild() method to be very similar, even though it is not encouraged.</p> <p>Let me show some (simplified) examples:</p> <p><strong>1. Heirarchy</strong></p> <pre><code>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; </code></pre> <p><strong>2. Grid</strong></p> <pre><code>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; </code></pre> <p>So essentially i am bypassing the RootNodeCount and OnInitNode methods/property and using the old fashioned way to add nodes to the tree. It seems to work fine. Note in the example i create and destroy my queries at runtime.</p> <p>The reason i started using the tree in this manner is that i could load all the data in the tree once and then free the TQuery after i had finished using it. I was thinking that regardless of keeping the TQuery alive/created i would still need to use my rData record to store the data, hence using up more memory if i did not destroy the TQuery. Currently my application uses about 250+MB when fully loaded, and can increase when i run SQL reports and display them in the VST. I have seen it use about 1GB of ram when i have run a SQL report with 20000+ nodes and 50+ columns. What i would like to know if the way i am using the VST incorrect with regards to minimizing memory usage?</p> <p>Would i be better off creating a query for the lifetime of the tree and using the onInitNode event? So that when data is requested by the tree it fetches it from the TQuery using the onInitNode/OnInitChildren event (i.e. the pure virtual paradigm of the tree)? Thus i would need to keep the TQuery alive for the duration of the form. Would there be any memory benefit/performance benefit in using it this way?</p> <p>In the above situations the i can see the difference for the grid example would be far less (if any) than the heirarchy - due to the fact that all nodes need to be initialized when populated.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload