devxlogo

Descendants of TTreeNode Not Compatible

Descendants of TTreeNode Not Compatible

Question:
I am having troubles with the TTreeView component and adding custom derivations of TTreeNodes to it. I want to define a new type of TTreeNode with a lot of extra parameters for my application (for example, an internal-timer for each item that does some polling, and so on) and then add that new node to a TTreeView. The problem is caused by this simplified subclass that I created of TTreeNode:

========== TUser Class ========================type  TUser  = Class( TTreeNode )  private    FSomeTimer : TTimer;    FUserTag   : String[10];  public    constructor Create( AOwner: TTreeNodes ); virtual;    destructor  Destroy; override;    //procedure   SetTag( s : String );  not relevant in example  end; { procedures follow }constructor TUser.Create( AOwner : TTreeNodes );begin inherited Create( AOwner ); FSomeTimer := TTimer.Create( nil ); FSomeTimer.Enabled := FALSE;end;destructor TUser.Destroy;begin  inherited Destroy; FSomeTimer.Free;end; ====================END TUser Class ================

When I try this next code, I receive a compiler event saying that it is not assignment compatible, which is understandable as it really isn’t:

var aUser : TUser;begin aUser := TreeView1.Items.Add( nil, 'some caption');end;

Also, if I were to type cast the result from the .Add, it would compile but crash at run time if I attempt to modify any of my “extended” properties.

However, when I try this line of code, it does compile and work, but the item does not actually show up on screen:

 aUser := TUser.Create( TreeView1.Items );

How can I solve this problem? Do I need to create some new type of TTreeView? If so, how is this possible?

Answer:
Think about this: When you make a call to the Add method, what by default gets created? A TTreeNode. TTreeView knows only about how to create a TTreeNode, not a descendant. That’s where your problem lies. If you look at the ComCtrls unit, you’ll see that TTreeView merely surfaces various protected properties of TCustomTreeView, and if you look at the code for AddChild of TCustomTreeView.Items.AddChild (or Add, etc.), you’ll see that this method creates new TTreeNodes. No matter what you try to do, you won’t be able to create the descendant by just calling the Add- methods. Furthermore, since TTreeNode methods cannot be overriden, you can’t subclass the methods to affect some sort of polymorphic behavior. So what do you do?

You have the right idea of creating descendants, so that’s a good start. What I’d do though is a bit different from what you did. Let’s start with what we know. First, TCustomTreeView’s Items property is of type TTreeNodes. Also, we know that TTreeNodes Add- methods create only TTreeNode objects. Furthermore, the Add- methods are static, so they can’t be overridden.

Given this information, I’d make sibling objects of both TTreeNodes and TTreeNode (copy the code from both objects to create your new siblings). Yes, this is a pain, but if you want to add your own stuff without losing the default behavior, this is the way to do it. You might want to call them TExTreeNodes and TExTreeNode, respectively. They’ll essentially mimic the behavior of their siblings, but have the added functionality.

Finally, you’ll have to make a sibling of TCustomTreeView because of how the class handles persistence. With TCustomTreeView, it reads and writes the Items property to and from disk to save the contents of the TreeView. Unfortunately, it’s expecting to read and write only TTreeNodes type. Luckily, even though you have to make a sibling, all you need to do with it is change the type Items points to your new TExTreeNodes type. You don’t need to do any further coding, unless you want to add some sort of extended Items property and then you’d have to hassle with persistence from that end. Not a good idea. Oh well, that’s my two-cents-worth….

devxblackblue

About Our Editorial Process

At DevX, we’re dedicated to tech entrepreneurship. Our team closely follows industry shifts, new products, AI breakthroughs, technology trends, and funding announcements. Articles undergo thorough editing to ensure accuracy and clarity, reflecting DevX’s style and supporting entrepreneurs in the tech sphere.

See our full editorial policy.

About Our Journalist