I want my component which will be non-visual to have its published properties under a category not on the top level of the Object Inspector.
Take the below example:<
Create a class that has those properties, and then give your component a single property of that class type. The property class should be a TPersistent
descendant:
type
TComponentProperties = class(TPersistent)
private
function GetSomeValue: string;
function GetSomeValueExt: string;
published
property SomeValue: string read GetSomeValue;
property SomeValueExt: string read GetSomeValueExt;
end;
TMyComponent = class(TComponent)
private
FProperties: TComponentProperties;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property Properties: TComponentProperties read FProperties;
end;
The component owns its property object, so it needs to be created and destroyed:
constructor TMyComponent.Create;
begin
inherited;
FProperties := TComponentProperties.Create;
end;
destructor TMyComponent.Destroy;
begin
FProperties.Free;
inherited;
end;
With that code, the component's properties should now be listed under the "Properties" item. It's not a category, though. Categories are something else entirely. Categories don't re-arrange the component; they just change how the properties are displayed in the Object Inspector. Note that with my code, TMyComponent
doesn't have any SomeValue
property anymore. Instead, it just has one property, Properties
, and that object has other properties. Consider whether that's really how you want consumers of your component to have to access it.
If the Properties
property is not read-only, then it needs to have a property setter; you cannot have it write directly to FProperties
. Write it like this:
procedure TMyComponent.SetProperties(const Value: TProperties);
begin
FProperties.Assign(Value);
end;
That also requires that you override the Assign
method to do the right thing:
procedure TComponentProperties.Assign(Other: TPersistent);
begin
if Other is TComponentProperties then begin
SomeValue := TComponentProperties(Other).SomeValue;
SomeValueEx := TComponentProperties(Other).SomeValueEx;
end else
inherited;
end;
We're also assuming that the property object's properties aren't read-only, either. When the property object's properties change, the owning object will probably want to know about it, so it should have an event that the component assigns a value to. When the properties change, they'll trigger the event.