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….

Share the Post:
Heading photo, Metadata.

What is Metadata?

What is metadata? Well, It’s an odd concept to wrap your head around. Metadata is essentially the secondary layer of data that tracks details about the “regular” data. The regular

XDR solutions

The Benefits of Using XDR Solutions

Cybercriminals constantly adapt their strategies, developing newer, more powerful, and intelligent ways to attack your network. Since security professionals must innovate as well, more conventional endpoint detection solutions have evolved

AI is revolutionizing fraud detection

How AI is Revolutionizing Fraud Detection

Artificial intelligence – commonly known as AI – means a form of technology with multiple uses. As a result, it has become extremely valuable to a number of businesses across

AI innovation

Companies Leading AI Innovation in 2023

Artificial intelligence (AI) has been transforming industries and revolutionizing business operations. AI’s potential to enhance efficiency and productivity has become crucial to many businesses. As we move into 2023, several

data fivetran pricing

Fivetran Pricing Explained

One of the biggest trends of the 21st century is the massive surge in analytics. Analytics is the process of utilizing data to drive future decision-making. With so much of