Component Development: Adding nested properties to the Object Inspector

When developing components it always comes to the point where you say: Do I really need that property? Does it make sense to offer even more customization?

I am always a fan of keeping the amount of customization limited to things that really will be used, but – let’s be honest – sometimes you can hardly imagine what people will be able to do with your components…

Thus, while developing a VCL component that generates a barcode using the Barcode4Me webservice API, I noticed that when adding all my properties the component looks rather cluttered in the Object Inspector. I have to admit that I never use the category arrangement for propties – ever since it has been introduced in Delphi 3. I never got used to it as the property was never in the category I expected it to be in. Thus, I always arrange “by Name”.

I might add that this post will be nothing out of the ordinary for the skilled Delphi developer. However, as it has been quite some time since I developed a VCL component that had a “nesting” of this sort, I needed to read up on the topic again. Here’s a write up…

The component offers context menu support and also a whole lot of properties to support the complete Barcode4Me API (link).

barcode_01

Note the property called “Properties” of type “TBarcodeProperties”. This property allows me to configure the properties of the Barcode and not the visual aspects of the component. The object inspector “magically” offers the nesting and sub-properties in a way:

properties

This magic happens if you rememer one basic rule:

Derive your “nested” types from TPersistent

Sounds easy enough. What is the reason for this? Well, Delphi needs to be able to serialize the object instance into the form file (dfm). In order to do that, your class needs to be derived from TPersistent .  The IDE starts with your form and serializes all “owned” components on the form, one after another.

TBarcodeProperties and TQRProperties are defined as follows:

It is important to provide the method Assign as values need to be assigned by value. For that reason we also use Assign for more nested types:

If we simply used FQRProperties := (Source as TBarcodeProperties).QR  we would be in big memory management trouble …
Thus, the component class also uses assign for the property “Properties”:

With memory management in mind we also need to instantiate “Properties” and free it when the component is freed:

Not that difficult after all, but yielding a much better developer experience when using the component as you can structure your properties in logical units. As far as I know, every professional component library with very customizable components uses this means to structure the properties.

Posted in Delphi Tagged with: ,

Leave a Reply

Your email address will not be published. Required fields are marked *

*