在FireMonkey组件中使用Tedit

时间:2016-12-25 13:30:46

标签: delphi firemonkey custom-component

我在Fire-monkey中创建了一个组件,并在其中创建了一个TEdit。 我的组件有一个名为 Value 的字符串属性,通过向其发送任何字符串,My Component将在Tedit中显示该属性。 在设计时每件事都可以。但在运行时,Tedit没有任何东西显示 我的代码是

true

我该怎么办?

2 个答案:

答案 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;