在Delphi下,我想创建一个新的firemonkey控件,它将包含另一个firemonkey控件。这不是一个真正的问题,因为我可以这样做:
constructor TMyComponent.Create(AOwner: TComponent);
begin
inherited;
FBtn := Trectangle.create(self);
FBtn.parent := self;
FBtn.stored := false;
end;
但是现在我想允许最终用户修改 Object Inspector 中FBtn的属性!我不知道该怎么办:(
如果我删除FBtn.stored:= False,那么我将在结构资源管理器中有一些名称为<组件[7]>每当我将表单视为文本并返回查看为表单时,结构资源管理器中将出现一个新组件:(
答案 0 :(得分:4)
您要在Objct Inspector中公开的任何内容都必须在published
属性中声明,例如:
type
TMyComponent = class(TComponent)
private
FBtn: TRectangle;
procedure SetBtn(Value: TRectangle);
published
property Btn: TRectangle read FBtn write SetBtn;
end;
constructor TMyComponent.Create(AOwner: TComponent);
begin
inherited;
FBtn := TRectangle.create(Self);
FBtn.Parent := Self;
FBtn.Stored := False;
FBtn.SetSubComponent(True);
end;
procedure TMyComponent.SetBtn(Value: TRectangle);
begin
FBtn.Assign(Value);
end;
答案 1 :(得分:3)
虽然雷米的答案在技术上会起作用,但我认为这不是合适的方法。这是因为当您将任何TComponent
后代发布为属性时,这假设您将在外部创建外部控件,然后在对象检查器中对其进行分配。当然,您不希望允许这种情况发生,因为此控件是在内部创建的。您也可能只希望允许用户更改某些属性,而不是所有属性。
相反,我建议使用TPersistent
,它只公开您实际想要提供访问权限的控件的那些属性。
unit MyComponentUnit;
interface
uses
System.Classes, System.SysUtils,
Fmx.Controls, FMX.StdCtrls, FMX.Objects;
type
TMyComponentButton = class(TPersistent)
private
FBtn: TRectangle;
function GetXRadius: Single;
function GetYRadius: Single;
procedure SetXRadius(const Value: Single);
procedure SetYRadius(const Value: Single);
//And any other property getters/setters you wish to wrap
public
constructor Create(ABtn: TRectangle);
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
published
property XRadius: Single read GetXRadius write SetXRadius;
property YRadius: Single read GetYRadius write SetYRadius;
//And any other properties you wish to wrap
end;
TMyComponent = class(TControl)
private
FBtn: TRectangle;
FMyComponentButton: TMyComponentButton;
procedure SetMyComponentButton(const Value: TMyComponentButton);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property MyComponentButton: TMyComponentButton
read FMyComponentButton write SetMyComponentButton;
end;
implementation
{ TMyComponentButton }
constructor TMyComponentButton.Create(ABtn: TRectangle);
begin
inherited Create;
FBtn:= ABtn;
end;
destructor TMyComponentButton.Destroy;
begin
inherited;
end;
procedure TMyComponentButton.Assign(Source: TPersistent);
begin
if Source is TMyComponentButton then begin
XRadius:= (Source as TMyComponentButton).XRadius;
YRadius:= (Source as TMyComponentButton).YRadius;
//And everything else you need to assign
end else
inherited;
end;
function TMyComponentButton.GetXRadius: Single;
begin
Result:= FBtn.XRadius;
end;
function TMyComponentButton.GetYRadius: Single;
begin
Result:= FBtn.YRadius;
end;
procedure TMyComponentButton.SetXRadius(const Value: Single);
begin
FBtn.XRadius:= Value;
end;
procedure TMyComponentButton.SetYRadius(const Value: Single);
begin
FBtn.YRadius:= Value;
end;
{ TMyComponent }
constructor TMyComponent.Create(AOwner: TComponent);
begin
inherited;
FBtn:= TRectangle.Create(Self);
FBtn.Parent:= Self;
FBtn.Stored:= False;
FMyComponentButton:= TMyComponentButton.Create(FBtn);
end;
destructor TMyComponent.Destroy;
begin
FreeAndNil(FMyComponentButton);
FreeAndNil(FBtn);
inherited;
end;
procedure TMyComponent.SetMyComponentButton(const Value: TMyComponentButton);
begin
FMyComponentButton.Assign(Value);
end;
end.