Как сгруппировать свойства моего компонента в Инспекторе объектов? - PullRequest
7 голосов
/ 24 февраля 2012

Я хочу, чтобы у моего компонента, который будет невизуальным, были опубликованные свойства в категории, находящейся не на верхнем уровне Инспектора объектов.

Возьмите следующий пример:

enter image description here

type
  TMyComponent = class(TComponent)
  protected
    function GetSomeValue: string;
    function GetSomeValueExt: string;
  published
    property SomeValue: string read GetSomeValue;
    property SomeValueExt: string read GetSomeValueExt;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('My Component', [TMyComponent]);
end;

function TMyComponent.GetSomeValue: string;
begin
  Result := 'test';
end;

function TMyComponent.GetSomeValueExt: string;
begin
  Result := 'extended..';
end;

Как мне заставить мой компонент зарегистрироваться в Инспекторе объектов с SomeValue и SomeValueExt в категории с именем что-то вроде MyProperties?

Иллюстрация:

enter image description here

Мой компонент потенциально может иметь много опубликованных свойств, и я бы предпочел, чтобы они заходили в подкатегорию собственного уровня Инспектора объектов, чтобы держать его в стороне от общих свойств, таких как Имя и Тег.

Спасибо:)

1 Ответ

17 голосов
/ 24 февраля 2012

Создайте класс с этими свойствами, а затем присвойте вашему компоненту единственное свойство этого типа класса. Класс свойства должен быть TPersistent потомком:

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;

Компонент владеет своим объектом свойства, поэтому его необходимо создать и уничтожить:

constructor TMyComponent.Create;
begin
  inherited;
  FProperties := TComponentProperties.Create;
end;

destructor TMyComponent.Destroy;
begin
  FProperties.Free;
  inherited;
end;

С этим кодом свойства компонента теперь должны быть перечислены в пункте «Свойства». Это не категория . Категории это что-то совершенно другое. Категории не переупорядочивают компонент; они просто изменяют способ отображения в Инспекторе объектов. Обратите внимание, что с моим кодом TMyComponent больше не имеет свойства SomeValue. Вместо этого у него есть только одно свойство, Properties и , что у объекта есть другие свойства. Подумайте, действительно ли вы хотите, чтобы потребители вашего компонента имели к нему доступ.


Если свойство Properties не только для чтения, то оно должно иметь установщик свойства; Вы не можете написать это прямо в FProperties. Напишите это так:

procedure TMyComponent.SetProperties(const Value: TProperties);
begin
  FProperties.Assign(Value);
end;

Для этого также необходимо переопределить метод Assign, чтобы поступить правильно:

procedure TComponentProperties.Assign(Other: TPersistent);
begin
  if Other is TComponentProperties then begin
    SomeValue := TComponentProperties(Other).SomeValue;
    SomeValueEx := TComponentProperties(Other).SomeValueEx;
  end else
    inherited;
end;

Мы также предполагаем, что свойства объекта свойства также не доступны только для чтения. Когда свойства объекта свойства изменяются, объект-владелец, вероятно, захочет узнать об этом, поэтому у него должно быть событие, которому компонент присваивает значение. Когда свойства изменяются, они вызывают событие.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...