Delphi Firemonkey:如何定义包含另一个组件的组件?
在Delphi下,我想创建一个新的firemonkey控件,该控件将包含另一个firemonkey控件。这不是一个真正的问题,因为我可以这样做:Delphi Firemonkey:如何定义包含另一个组件的组件?,delphi,firemonkey,Delphi,Firemonkey,在Delphi下,我想创建一个新的firemonkey控件,该控件将包含另一个firemonkey控件。这不是一个真正的问题,因为我可以这样做: constructor TMyComponent.Create(AOwner: TComponent); begin inherited; FBtn := Trectangle.create(self); FBtn.parent := self; FBtn.stored := false; end; 但是现在我想允许最终用户在对象检查
constructor TMyComponent.Create(AOwner: TComponent);
begin
inherited;
FBtn := Trectangle.create(self);
FBtn.parent := self;
FBtn.stored := false;
end;
但是现在我想允许最终用户在对象检查器中修改FBtn的属性!我不知道怎么做:(
如果我删除FBtn.stored:=False,那么我将在结构资源管理器中有一些名为
已发布的
属性中声明,例如:
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;
虽然里米的回答在技术上是可行的,但我不认为它是合适的方法。这是因为当你发布任何<代码> TStuts<代码>子孙作为一个属性时,假定你会在外部创建这样的控件,然后在对象检查器中分配它。当然,你不想允许这种情况发生,因为控件是在内部创建的。您可能只希望允许用户更改某些属性,而不是所有属性 相反,我建议使用
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.
尝试在TMyComponent.Create中添加FBtn.SetSubcomponent(true)。在vcl中工作良好,在firemonkey中也应该工作,如果他们不是非常疯狂的话……不是的,如果我使用FBtn.SetSubcomponent,没有任何改变(true)在结构资源管理器中我仍然会有奇怪的组件名称:(以某种方式FBtn.SetSubcomponent(true)像FBtn.Stored一样工作……您的
TMyComponentButton
类未实现Assign()
@remy是的,这取决于op来决定如何实现。只需奠定基本概念。你至少可以展示如何为你创建的属性实现它。属性不必公开外部类。想想TFont等。谢谢它的工作!!在对象检查器中只需一个remak,我的名字像MyComponent 1…是p吗例如,是否可以改用MyComponent 1.button1这样的名称?这并不重要anyway@loki你所描述的没有意义。请澄清。雷米,如果我在“事件”选项卡上尝试向收到的子组件添加事件,我知道我想用你的方法(看起来正是我想要的)说什么“无法为未命名组件创建方法”:(当然不是,因为子组件的Name
属性尚未分配值。您确实不应该向用户公开子组件的事件。主组件应该为子组件的事件分配自己的处理程序,然后主组件可以向用户公开自己的事件。