How do I group my component's properties in the Object Inspector?

前端 未结 1 710
离开以前
离开以前 2021-01-05 06:06

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:<

1条回答
  •  不知归路
    2021-01-05 06:23

    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.

    0 讨论(0)
提交回复
热议问题