我在Fire-monkey中创建了一个组件,并在其中创建了一个TEdit。 我的组件有一个名为 Value 的字符串属性,通过向其发送任何字符串,My Component将在Tedit中显示该属性。 在设计时每件事都可以。但在运行时,Tedit没有任何东西显示 我的代码是
true
我该怎么办?
答案 0 :(得分:2)
你应该使用FireMonkey中的样式来做这种事情,所以对于你的例子,你需要MyComponent.style
文件如下
object TRectangle
StyleName = 'MyComponentStyle'
Align = Center
Fill.Color = xFFF0F0F0
HitTest = False
Size.Width = 159.000000000000000000
Size.Height = 131.000000000000000000
Size.PlatformDefault = False
Stroke.Color = xFFCCCCCC
object TEdit
StyleName = 'MyComponentEditStyle'
Touch.InteractiveGestures = [LongTap, DoubleTap]
Align = Scale
TabOrder = 0
Size.Width = 79.499755859375000000
Size.Height = 21.833337783813480000
Size.PlatformDefault = False
end
end
然后您需要在项目文件中包含MyComponent.rc
,如下所示
MyComponentStyle RCDATA "MyComponent.style"
,您的MyComponent.pas
将
unit MyComponent;
interface
uses System.Classes, FMX.Types, FMX.Controls, FMX.StdCtrls, FMX.Edit, FMX.Styles;
type
TMyComponent = class(TPanel)
private
{ Private declarations }
FEdit: TEdit;
FValue: string;
procedure SetValue(const AValue: string);
function GetValue: string;
protected
{ Protected declarations }
procedure FreeStyle; override;
procedure ApplyStyle; override;
function GetStyleObject: TFmxObject; override;
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
published
{ Published declarations }
property Value: string read GetValue write SetValue;
end;
procedure Register;
implementation
uses Winapi.Windows;
{$R MyComponent.res}
procedure Register;
begin
RegisterComponents('Samples', [TMyComponent]);
end;
procedure TMyComponent.ApplyStyle;
begin
inherited;
if FindStyleResource<TEdit>('MyComponentEditStyle', FEdit) then
begin
FEdit.Visible := True;
FEdit.Text := Value;
end;
end;
function TMyComponent.GetStyleObject: TFmxObject;
const
Style = 'MyComponentStyle';
begin
if (StyleLookup = '') then
Result := TStyleStreaming.LoadFromResource(HInstance, Style, RT_RCDATA)
else
Result := inherited GetStyleObject;
end;
procedure TMyComponent.FreeStyle;
begin
FEdit := nil;
inherited;
end;
constructor TMyComponent.Create(AOwner: TComponent);
begin
inherited;
Width := 100;
Height := 100;
end;
procedure TMyComponent.SetValue(const AValue: string);
begin
FValue := AValue;
if Assigned(FEdit) then
begin
FEdit.Text := FValue;
end;
end;
function TMyComponent.GetValue: string;
begin
Result := FValue;
end;
end.
答案 1 :(得分:1)
最初我认为您在运行时创建和使用组件时遇到了问题。在运行时实例化和使用组件非常正常。
在EugeneK的评论之后,我现在明白该组件不起作用,如果你在设计时实例化它并尝试在运行时更改TEdit
的text属性。
原因可以追溯到这样一个事实,即你的组件是一个组合类型,并且是由子组件构建的(好吧,只有TEdit
)。如果子组件的Stored
属性未设置为False
,则它们可能会在设计时多次流式传输,f.ex。当您在表单的表单视图和文本视图之间切换时。
请参阅documentation并向下滚动至 TCalender:Constructed Complexity ,您可在其中找到以下内容:
组件树中的每个对象都将其Stored属性设置为 False及其Locked属性设置为True。禁用存储会阻止 该对象从Form流式传输到.fmx文件 设计师。如果未禁用存储属性,则子组件将禁用 在加载时冗余创建。
将表单视图切换到文本视图两次后的结果:
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
虽然这应该是这样的:
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
冗余的TEdit
控件将覆盖您在构造函数中创建的控件。
代码的更正: 添加标记的行
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;