Felipe
Felipe

Reputation: 283

Values of a property at design time, doesn't appear at run time

I have the following component which contains a property derived from a custom class:

unit MyComponentTest3;

interface

uses  Windows, ExtCtrls,Classes,Controls;

type

  TMyClass3 = class
    myString: string;
    myNumber: double;
  end;

  TMyComponentTest3 = class(TCustomPanel)
  private
    FMyProperty: TMyClass3;

    procedure SetMyProperty(Value: TMyClass3);
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;

    procedure SetMyPropertyPublic(AmyString: string; AmyNumber: double);
  published
    property MyProperty: TMyClass3 read FMyProperty write SetMyProperty;
  end;

procedure Register;

implementation


procedure Register;
begin
  RegisterComponents('MyComponents', [TMyComponentTest3]);
end;

{ TMyComponentTest3 }

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

  FMyProperty:= TMyClass3.Create;

end;

destructor TMyComponentTest3.Destroy;
begin
  FMyProperty.Free;

  inherited;
end;

procedure TMyComponentTest3.SetMyProperty(Value: TMyClass3);
begin
with FMyProperty do
  begin
    myString:= Value.myString;
    myNumber:= Value.myNumber;
  end;
end;

procedure TMyComponentTest3.SetMyPropertyPublic(AmyString: string;
  AmyNumber: double);
var
  auxMyProperty: TMyClass3;
begin

  auxMyProperty:= TMyClass3.Create;

  with auxMyProperty do
  begin
    myString:= AmyString;
    myNumber:= AmyNumber;
  end;

  SetMyProperty(auxMyProperty);

  auxMyProperty.Free;

end;

end.

It works fine, but when I set the values of the property at design time and run the program the values disappear. The same problem I get if I set the values of the component, save everything and when I load the values are not there anymore...

I guess the problem is because I am creating an instance of the custom class all the time, but I am not sure, and I don't know how to get around that. Do anyone has an idea of what can I do?

Upvotes: 2

Views: 1639

Answers (2)

Daeung Kwon
Daeung Kwon

Reputation: 1

constructor TMyComponentTest3.Create(AOwner: TComponent);
begin
  inherited;
  FMyProperty := TMyClass3.Create;
  FMyProperty.SetSubComponent(True);
end;

Upvotes: 0

Remy Lebeau
Remy Lebeau

Reputation: 598029

TMyClass3 needs to derive from TPersistent in order to be streamable in a DFM. It should also optionally override the virtual Assign() method, which SetMyProperty() would then be able to call.

Try this:

unit MyComponentTest3;

interface

uses
  Windows, ExtCtrls, Classes, Controls;

type

  TMyClass3 = class(TPersistent)
  private
    FMyString: string;
    FMyNumber: double;
  public
    procedure Assign(Source: TPersistent); override;
  published 
    property myString: string read FMyString write FMyString;
    property myNumber: double read FMyNumber write FMyNumber;
  end;

  TMyComponentTest3 = class(TCustomPanel)
  private
    FMyProperty: TMyClass3;

    procedure SetMyProperty(Value: TMyClass3);
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;

    procedure SetMyPropertyPublic(AmyString: string; AmyNumber: double);
  published
    property MyProperty: TMyClass3 read FMyProperty write SetMyProperty;
  end;

procedure Register;

implementation


procedure Register;
begin
  RegisterComponents('MyComponents', [TMyComponentTest3]);
end;

{ TMyClass3 }

procedure TMyClass3.Assign(Source: TPersistent);
begin
  if Source is TMyClass3 then
  begin
    with TMyClass3(Source) do
    begin
      Self.FMyString := myString;
      Self.FMyNumber := myNumber;
    end;
  end else
    inherited;
end;

{ TMyComponentTest3 }

constructor TMyComponentTest3.Create(AOwner: TComponent);
begin
  inherited;
  FMyProperty := TMyClass3.Create;
end;

destructor TMyComponentTest3.Destroy;
begin
  FMyProperty.Free;
  inherited;
end;

procedure TMyComponentTest3.SetMyProperty(Value: TMyClass3);
begin
  FMyProperty.Assign(Value);
end;

procedure TMyComponentTest3.SetMyPropertyPublic(AmyString: string; AmyNumber: double);
begin
  with MyProperty do
  begin
    myString := AmyString;
    myNumber := AmyNumber;
  end;  
end;

end.

Upvotes: 5

Related Questions