如何更改Margins属性的默认值?

时间:2013-12-25 17:27:09

标签: delphi components delphi-xe2

使用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 个答案:

答案 0 :(得分:7)

您可以使用自己的默认设置声明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属性有一个只能分配到边距(左,右......)的setter。代码永远不会写入支持字段,但它仍然有效。这条线

Margins := TMyMargins.Create(Self);

实际相同

TMyMargins.Create(Self);

也可以。

通过“作品”我的意思是,它有效。边缘,f.i.,被正确销毁,而不是因为所有权等。(边缘i 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;