如何在创建中设置TCustomControl的Parent

时间:2011-06-19 15:14:09

标签: delphi

当我们将组件创建为自定义控件并且控件放在面板上时,控件始终显示在窗体而不是包含控件上。如何在Create中设置自定义控件的父级,以便在面板上删除按钮时父级按钮是面板?

TGlassButton = class(TCustomControl)
...
public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
...

constructor TGlassButton.Create(AOwner: TComponent);
  begin
    inherited;  ???????????
    inherited Create(AOwner); ????????????
    Parent := TWinControl( AComponent ); ??????????????
    ...
  end;

问题是设计时创建而不是运行时。这非常有效:

procedure TForm10.FormCreate(Sender: TObject);
begin
  GlassButton0 := TGlassButton.Create( Panel1 );
  GlassButton0.Parent := Panel1;
  GlassButton0.Left := 20;
  GlassButton0.Top := 6;
  GlassButton0.Width := 150;
  GlassButton0.Height := 25;
  GlassButton0.Caption := 'Created At RunTime';
end;

3 个答案:

答案 0 :(得分:4)

父母应该由创建控件的人设置。对于在设计时创建的控件,这将在创建表单时由流系统完成。对于在运行时创建的控件,应该在创建控件时完成:

var
  Control: TWinControl;
begin
  Control := TGlassButton.Create(<Form or Application>);
  Control.Parent := <Some other control on the form>;
end;

请注意,一般而言,无论父母如何,表格都是其所有控件的所有者。控件的父级是/应该是负责绘制它的控件:换句话说,它是视觉上的控件。即Panel,TabSheet,GroupBox或其他一些容器。

答案 1 :(得分:4)

不要在构造函数中设置Parent属性!正如其他人所说,IDE和DFM流系统将在构造函数退出后自动分配Parent。如果需要在构造函数中执行依赖于父分配的操作,则需要重新设计组件。覆盖虚拟SetParent()和/或Loaded()方法,然后从那里执行操作。并且在可以避免在设计时实际不需要的操作的地方使用if (csDesigning in ComponentState) then ...检查。

答案 2 :(得分:0)

我也陷入了这个麻烦 就我而言,解决方案是:

  1. 不要在创建
  2. 中设置父级
  3. 不要在创建
  4. 中设置需要窗口句柄的属性

    详细说明: "Control '' has no parent window" error