Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 如何创建具有子面板的自定义控件,该子面板在设计时接受其他控件?_Delphi_Custom Component - Fatal编程技术网

Delphi 如何创建具有子面板的自定义控件,该子面板在设计时接受其他控件?

Delphi 如何创建具有子面板的自定义控件,该子面板在设计时接受其他控件?,delphi,custom-component,Delphi,Custom Component,我编写了一个自定义控件,它有几个子面板。我希望这些子面板能够接受在设计时放置在其上的任何附加控件 不幸的是,在设计时丢弃的任何控件最终都会出现在我的自定义控件上,而不是面板上。如果我尝试删除标签,这会特别显示:标签的蓝色圆点会显示,但标题不会显示,如果我取消选择标签,它将不再可见 简化代码(仅一个子面板): 我做错了什么 (以防万一:我使用的是Delphi2007。) [编辑] 我现在以不同的方式解决了这个问题。该构件不再包含面板,而是指外部面板。这使得它实际上更加灵活,但在缺点是它不再是直观的

我编写了一个自定义控件,它有几个子面板。我希望这些子面板能够接受在设计时放置在其上的任何附加控件

不幸的是,在设计时丢弃的任何控件最终都会出现在我的自定义控件上,而不是面板上。如果我尝试删除标签,这会特别显示:标签的蓝色圆点会显示,但标题不会显示,如果我取消选择标签,它将不再可见

简化代码(仅一个子面板):

我做错了什么

(以防万一:我使用的是Delphi2007。)

[编辑]

我现在以不同的方式解决了这个问题。该构件不再包含面板,而是指外部面板。这使得它实际上更加灵活,但在缺点是它不再是直观的使用


我仍然想知道如何实现我最初描述的目标。有没有一个开源组件可以做到这一点,这样我就可以研究源代码了?

从细节上我看不出来,但您是否将标签的父级设置为子面板?如果是在设计时,您可能需要在主组件(例如面板所在的容器)中编写代码,以确定哪个子面板接受该组件,并将labels parent属性设置为该子面板


我敢肯定,当一个组件被添加或从另一个组件中删除时,会调用a通知方法,这将有助于您跟踪需要将代码放在哪里。

这是一个好问题。通过将csAcceptControls添加到controls ControlStyle属性,可以允许自定义TWinControl在设计时删除其他控件

constructor TMyContainer.Create(AOwner: TComponent);
begin
  inherited;
  ControlStyle := ControlStyle + [csAcceptControls];
end;
但为了解决这个问题,我在将控件放到自定义控件内的子面板上方面几乎没有成功。将csAcceptControls添加到子面板的ControlStyle是不够的。我得到的最有说服力的东西是让小组相信它是这样设计的:

type
  TGiveMeProtected_Component = class(TComponent);

procedure TMyContainer.Create(AOwner: TComponent);
begin
  FSubPanel := TPanel.Create(Self);
  TGiveMeProtected_Component(FSubPanel).SetDesigning(True, True);
end;

使用该代码,您现在可以将控件放到子面板上,但这意味着您还可以选择子面板,更改其属性,甚至删除您明确不想要的子面板。很抱歉,我想不出答案,我还是很想知道你是否能找到答案

我这样做了,但最终用常规面板替换了控件,这些面板在需要时会显示/隐藏

我的控件不是从TPanel下降,而是从TCustomControl下降。我不认为我可以从TPanel下载,但我不记得是什么问题

容器控件:

TPageControl = class(TCustomControl)
private
  PageList:TObjectList;  // To hold references to all sub-pages for easy access.
end;

constructor TPageControl.Create(AOwner: TComponent);
begin
  inherited;
  ControlStyle := ControlStyle + [csAcceptsControls];
  PageList := TObjectList.Create;
  PageList.OwnsObjects := false;
end;

destructor TVstPageControl.Destroy;
begin
  PageList.Free;
  inherited;
end;

procedure TPageControl.NewPage;
var
  Page:TPage;
begin
  Page := TPage.Create(Self.Owner);
  Page.Parent := Self;
  Page.Align := alClient;

  PageList.Add(Page);
end;

procedure TPageControl.DeletePage(Index:integer);
var
  Page:TPage;
begin
  Page := PageList[Index] as TPage;
  Page.Free;
  PageList.Delete(Index);
end;
TVstPage = class(TCustomControl)
public
  constructor Create(AOwner: TComponent); override;
end;

constructor TPage.Create(AOwner: TComponent);
begin
  inherited;
  ControlStyle := ControlStyle + [csAcceptsControls];
end;
页面/子面板控件:

TPageControl = class(TCustomControl)
private
  PageList:TObjectList;  // To hold references to all sub-pages for easy access.
end;

constructor TPageControl.Create(AOwner: TComponent);
begin
  inherited;
  ControlStyle := ControlStyle + [csAcceptsControls];
  PageList := TObjectList.Create;
  PageList.OwnsObjects := false;
end;

destructor TVstPageControl.Destroy;
begin
  PageList.Free;
  inherited;
end;

procedure TPageControl.NewPage;
var
  Page:TPage;
begin
  Page := TPage.Create(Self.Owner);
  Page.Parent := Self;
  Page.Align := alClient;

  PageList.Add(Page);
end;

procedure TPageControl.DeletePage(Index:integer);
var
  Page:TPage;
begin
  Page := PageList[Index] as TPage;
  Page.Free;
  PageList.Delete(Index);
end;
TVstPage = class(TCustomControl)
public
  constructor Create(AOwner: TComponent); override;
end;

constructor TPage.Create(AOwner: TComponent);
begin
  inherited;
  ControlStyle := ControlStyle + [csAcceptsControls];
end;