Why is Delphi TTreeNodes fundamentally tied to TCustomTreeView?

1.2k views Asked by At

I'm trying to build several 'trees' in memory, and later assign one of them to a TTreeView control that the user can interact with. However, I can't construct any TTreeNodes objects without passing a pointer to an existing TTreeView. Passing in NIL causes AVs.

Two questions:- What's the reason for this "hard" linking between TTreeNodes and TTreeViews, and, what's the best way of solving the problem?

Some options I can see are:

  • Maintaining my own tree structure without ttreenodes and dynamically building the TTreeNodes as required.
  • Having multiple invisible TTreeView objects that are just used to make the TTreeNodes stuff work.

.. but I haven't weighed up pros and cons for these.

3

There are 3 answers

1
Rob Kennedy On BEST ANSWER

There is a lot of code in TTreeView and its related classes to keep the link between the Delphi objects and the underlying Windows control in sync. When nodes are added directly via window messages, the Delphi object needs to reflect that change the very next time you ask it how many nodes it has, for example.

TTreeView is a wrapper for the Windows control, and TTreeNodes and TTreeNode are simply part of that wrapper. They don't actually implement all the tree operations that the control does. Certain operations are invalid if there currently isn't any Windows control available.

TTreeView is a visual control. If you don't have anything to visualize, then it's not the control for you. If you have multiple tree data structures, and you only want one tree control, then you're going to have to live with destroying and re-creating the tree nodes whenever you switch to a different structure. The control doesn't even provide a way to hide certain nodes temporarily.

You might be interested in Mike Lischke's virtual tree control. In its intended usage, you manage the tree data structure yourself; the control is just a visualization. It asks you how many children each node has, and then it asks you what the text of each node is each time it has to draw that node. It managed which nodes are expanded, selected, checked, or visible, but you manage all the data. It is free and open-source.

0
Henk Holterman On

The (main) reason would likely be to prevent you from having a TTreeNode appear in more than 1 TTreeview. It is a common design pattern, also found in XmlNode classes etc.

As for your 2 options, hard to say without knowing more about the what/how/how many in your project.

If there are the slightest differences in appearance/behavior associated with the Node sets I would go for swapping TTreeviews.

2
Toon Krijthe On

If you look at the source of TTreeNodes, you see that it requires the Owner (which is a TCustomTreeView). You can use a hidden treeview or create a custom subclass.

I prefer to separate gui from datamodel. So there is always a datamodel with the correct relations.