I have created a component in Fire-monkey and also created a TEdit inside it. My component has a String Property named Value that by pouting any string to it , My Component will show that in Tedit. at design Time every thing is OK. but at Run time no thing shows in Tedit My Code is
type
TMyComponent = class(TPanel)
private
{ Private declarations }
Edit:TEdit;
FValue:String;
Procedure SetValue(Const Value:String);
protected
{ Protected declarations }
Constructor Create(Aoner:TComponent); Override;
Destructor Destroy; Override;
public
{ Public declarations }
published
{ Published declarations }
Property Value:String Read FValue Write SetValue;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Samples', [TMyComponent]);
end;
Constructor TMyComponent.Create(Aoner:TComponent);
begin
Inherited;
Width:=100;
Height:=100;
Edit:=TEdit.Create(Self);
Edit.Parent:=Self;
Edit.Width:=30;
Edit.Text:='';
Edit.Align:=TAlignLayout.Scale;
end;
Procedure TMyComponent.SetValue(const Value: string);
begin
FValue:=Value;
Edit.Text:=FValue;
end;
Destructor TMyComponent.Destroy;
begin
Edit.Destroy;
Inherited Destroy;
end;
end.
What Should I do?
Initially I thought you were having problems both with creating and using your component at runtime. Instantiating and using your component at runtime works perfectly ok.
After the comment by EugeneK I now understand that the component doesn't work, if you instantiate it at design time and attempt to change the text property of the TEdit
at runtime.
The reason can be traced to the fact that your component is a composed type and constructed from subcomponents (well, only a TEdit
). If the Stored
property of the subcomponent(s) are not set to False
they might get streamed several times at design time, f.ex. when you switch between form view and text view of the form.
See documentation and scroll down to TCalender: Constructed Complexity where you can find the following:
Every object in the component tree has its Stored property set to False and its Locked property set to True. Disabling Stored prevents the object from being streamed out to the .fmx file by the Form Designer. If the Stored property is not disabled, subcomponents would be redundantly created when loading.
The result after switching the form view to text view twice:
object MyComponent1: TMyComponent
Position.X = 8.000000000000000000
Position.Y = 8.000000000000000000
Size.Width = 100.000000000000000000
Size.Height = 100.000000000000000000
Size.PlatformDefault = False
TabOrder = 5
object TEdit
Touch.InteractiveGestures = [LongTap, DoubleTap]
Align = Scale
TabOrder = 1
Size.Width = 90.000000000000000000
Size.Height = 18.333332061767580000
Size.PlatformDefault = False
end
object TEdit
Touch.InteractiveGestures = [LongTap, DoubleTap]
Align = Scale
TabOrder = 0
Size.Width = 90.000000000000000000
Size.Height = 18.333332061767580000
Size.PlatformDefault = False
end
end
while this is how it should look like:
object MyComponent1: TMyComponent
Position.X = 8.000000000000000000
Position.Y = 8.000000000000000000
Size.Width = 100.000000000000000000
Size.Height = 100.000000000000000000
Size.PlatformDefault = False
TabOrder = 5
end
The redundant TEdit
controls will cover the one you create in the constructor.
The correction to your code: Add the marked line
constructor TMyComponent.Create(Aoner: TComponent);
begin
inherited;
Width:=100;
Height:=100;
Edit:=TEdit.Create(Self);
Edit.Parent:=Self;
Edit.Width:=90;
Edit.Align:=TAlignLayout.Scale;
Edit.Stored := False; // *** add this line ***
end;