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