Have a look at the rmTreeNonView
component in rmControls library.
We've been using a modified version of that tree for years as a data container. It's free, fast, non-visual, comes with source code, and is easy to get started with because duplicates TTreeView's methods and properties almost 100%, plus adds some methods of its own--particularly, a fast hash-based search for tree node paths.
I doubt the company is in business any more (http://www.mills-enterprise.ca), but the rmControls package including source is available on many Delphi download sites.
EDIT:
Here's some code showing how to point to nodes in another tree structure from nodes of a VTV...hope I've included enough code to let you see what's going on. TmwDataTreeNode is a node of a TTreeNonView descendant. Note that when the PopulateVT method has completed, the ContextNode field of each TNodeData points to a node in the source data container tree. Note this approach does not make use of VTV's virtual nature, which might more likely be more appropriate for your situation.
type
//Virtual tree record stuff
PNodeData = ^TNodeData;
TNodeData = record
public
NodeSelf: PVirtualNode; //Ptr to our own VT node...needed?
ContextNode: TmwDataTreeNode; //ptr to our corresp node of data tree
GridRecordIndex: integer; //Grid.RecordIndex of our corresp Alloc formula.
end;
procedure T_fmExplAllocOut.PopulateVT;
{ Load data to the DragDrop treeview. }
var
n: TmwDataTreeNode; //Pointer to a node of my customized TTreeNonView
begin
VT.NodeDataSize := SizeOf(TNodeData);
VT.BeginUpdate;
vtsChangeFontSize(VT, Self.Font.Size); //Set Tree Font.Size & DefaultNodeHeight
//Add DragDrop Tree nodes
n := AllocController.SnapContext.Tree.Items.GetFirstNode;
while n <> nil do begin
AddVTNode(nil, n); //nil=parent node of top-level VT nodes
n := n.GetNextSibling;
end;
VT.FullExpand;
VT.EndUpdate;
end;
procedure T_fmExplAllocOut.AddVTNode(VTParentNode: PVirtualNode; n: TmwDataTreeNode);
{ Recursively add n & its children to VT. }
var
NodeData: PNodeData;
VTNode: PVirtualNode;
begin
if (n = nil) or not NodeInIncludeFilter(n) then
exit;
//Add this node
VTNode := VT.AddChild(VTParentNode);
NodeData := VT.GetNodeData(VTNode);
VT.ValidateNode(VTNode, False); //else OnFreeNode won't get called
with NodeData^ do begin
NodeSelf := VTNode;
ContextNode := n;
GridRecordIndex := -1;
end;
//Add child nodes
n := n.GetFirstChild;
while n <> nil do begin
AddVTNode(VTNode, n); //Pass our added node as Parent
n := n.GetNextSibling;
end;
end;
TVirtualNode
itself. – FuzzTVirtualNode
is not a solution. – Reproofhe needs to keep the data into a separate data structure outside the VT
but data are already separated. – FuzzTVirtualNode
orTNodeArray
array of that. It's the VT's natural type. – FuzzIndex
,Parent
,PrevSibling
,NextSibling
,FirstChild
,LastChild
what is even more than enough to use it. – FuzzIndex
,Parent
andLevel
(for faster iteration through the certain node level) and several functions for manipulation with it. – FuzzParent
andLevel
are fine until you want to modify the structure. Maintaining them becomes non-trivial. – Renaissance