delphipropertiescomponentsdesign-time

Published properties defaults reset in Design-time


I'm developing some components - custom buttons. I installed it, but in design-time custom published properties resets to zeros. First of all I'm talking about colors - it resets to clBlack (or for clBtnFace for Color property). Caption reset to empty string. I mean when I drop component to form in design-time all custom properties in Object Inspector reset to zero (colors to clBlack and so on). I can change it manually but why don't work default values that I set in code? The problem is only in design-time. When I create component in run-time it works fine. Here is code (take for example Color property).

Base class

TpfCustomButton = class(TCustomControl)
...
published
...
  property Color;
...
end;

Main code

TpfCustomColoredButton = class(TpfCustomButton)
...
public
  constructor Create(AOwner: TComponent);
...
end;

constructor TpfCustomColoredButton.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);

  Color := $00E1E1E1;//Look at this: setting Color
  ...
end;

Component Code

TpfColoredButton = class(TpfCustomColoredButton)
published
  ...
  property Action;
  property Align;
  //And some other standard properties
end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('PF Components', [TpfColoredButton]);
end;
...

Furthermore, just for test I'm trying so code:

TpfColoredButton = class(TpfCustomColoredButton)
  public
    constructor Create(AOwner: TComponent);
  ...  
  
constructor TpfColoredButton.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Caption := 'abc';
end;

And in design-time Caption was empty, but again, if I create it in run-time we see the Caption=abc as we expect. In run-time I create new object like this (and it works OK):

TForm2 = class(TForm)  
  procedure FormCreate(Sender: TObject);
private
  pf: TpfColoredButton;
end;

procedure TForm2.FormCreate(Sender: TObject);
begin
  pf := TpfColoredButton.Create(Self);
  pf.Parent := Self;
end;

Solution

  • You are changing the default value of the property in your derived class constructor, but you are not specifying the same default value in the property declaration to update its RTTI, which is used by the Object Inspector and DFM streaming.

    Also, you are missing override on your derived constructors. This is why your properties are not getting initialized properly when creating the components at design-time. Your derived constructors are not even being called. Whereas at run-time, you are calling the derived constructors directly.

    Change this:

    TpfCustomColoredButton = class(TpfCustomButton)
      ...
    public
      constructor Create(AOwner: TComponent);
      ...
    end;
    

    To this:

    TpfCustomColoredButton = class(TpfCustomButton)
      ...
    published
      ...
      property Color default $00E1E1E1;
      ...
    public
      constructor Create(AOwner: TComponent); override;
      ...
    end;
    

    Do the same with all other published properties of derived classes that have different default values than their base classes.