Как изменить значение по умолчанию для свойства поля?

используя мастер Delphi XE2 для создания компонента, я выбрал TPanel для наследования и изменил значения по умолчанию некоторых свойств в соответствии с моим приложением.

моя проблема в том, чтобы изменить значение по умолчанию поля:

  TControl = class(TComponent)
    ...
    property Margins: TMargins read FMargins write SetMargins;

Margins-это класс TMargin, объявленный с 4 свойствами, которые мне нужно переопределить по умолчанию:

  TMargins = class(TPersistent)
  published
    property Left: TMarginSize index 0 read FLeft write SetMargin default 3;
    property Top: TMarginSize index 1 read FTop write SetMargin default 3;
    property Right: TMarginSize index 2 read FRight write SetMargin default 3;
    property Bottom: TMarginSize index 3 read FBottom write SetMargin default 3;

Я могу / буду устанавливать в коде поля, когда вызывается конструктор компонента, однако я понятия не имею, как переопределите эти значения по умолчанию выше, чтобы отображаться в Редакторе свойств.

1 ответов


вы можете объявить свой TMargins потомок по умолчанию для использования в панели

type
  TMyMargins = class(TMargins)
  protected
    class procedure InitDefaults(Margins: TMargins); override;
  published
    property Left default 10;
    property Top default 10;
    property Right default 10;
    property Bottom default 10;
  end;

class procedure TMyMargins.InitDefaults(Margins: TMargins);
begin
  with Margins do begin
    Left := 10;
    Right := 10;
    Top := 10;
    Bottom := 10;
  end;
end;


затем, когда вы создаете свою панель, отклоните существующую и используйте свою

  TMyPanel = class(TPanel)
  private
    procedure DoMarginChange(Sender: TObject);
  public
    constructor Create(AOwner: TComponent); override;
  end;

constructor TMyPanel.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Margins.Free;
  Margins := TMyMargins.Create(Self);
  Margins.OnChange := DoMarginChange;
end;

procedure TMyPanel.DoMarginChange(Sender: TObject);
begin
  // same as in TControl which is private
  RequestAlign;
end;

поля будут храниться в dfm только тогда, когда они отличаются от значений по умолчанию.



хотя я не знаю, почему это работает... Проблема с выше кода Margins свойство имеет сеттер, который только присваивает полям (слева, справа..). Код никогда не записывается в поле поддержки, но он все еще работает. Линия

Margins := TMyMargins.Create(Self);

фактически же

TMyMargins.Create(Self);

, который также работает.

под "работает" я имею в виду, это работает. Поля, f.Я., уничтожается должным образом, а не из-за владения и т. д.. (поля iş a TPersistent, Не компонент), но прямо, когда Асцендент TControl звонки FMargins.Free.

в любом случае, поскольку я не понимаю, как это работает, как более безопасный, хотя и хакерский подход, я бы использовал это:

constructor TMyPanel.Create(AOwner: TComponent);
var
  Addr: NativeUInt;
begin
  inherited Create(AOwner);

  Addr := NativeUInt(@Margins);
  Margins.Free;
  PUINT_PTR(Addr)^ := NativeUInt(TMyMargins.Create(Self));
  Margins.OnChange := DoMarginChange;
end;