Reputation: 283
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
Reputation: 1
constructor TMyComponentTest3.Create(AOwner: TComponent);
begin
inherited;
FMyProperty := TMyClass3.Create;
FMyProperty.SetSubComponent(True);
end;
Upvotes: 0
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