gpt4 book ai didi

delphi - 自定义控件中的子面板是否可以接受设计器的控件?

转载 作者:行者123 更新时间:2023-12-02 04:59:49 25 4
gpt4 key购买 nike

我创建了一个继承自 Tcustom 控件的简单测试控件,其中包含 2 个面板。第一个是与顶部对齐的标题和与 alclient 对齐的客户端面板。

我希望客户端面板接受来自设计器的控件,虽然我可以将控件放置在面板上,但它们在运行时不可见,并且在项目关闭时无法正确保存。

该控件的示例代码如下

unit Testcontrol;

interface
uses Windows,System.SysUtils, System.Classes,System.Types, Vcl.Controls,
Vcl.Forms,Vcl.ExtCtrls,graphics,Messages;

type
TtestControl = class(TCustomControl)
private
FHeader:Tpanel;
FClient:Tpanel;
protected
public
constructor Create(Aowner:Tcomponent);override;
destructor Destroy;override;
published
property Align;
end;

implementation

{ TtestControl }

constructor TtestControl.Create(Aowner: Tcomponent);
begin
inherited;
Fheader:=Tpanel.create(self);
Fheader.Caption:='Header';
Fheader.Height:=20;
Fheader.Parent:=self;
Fheader.Align:=altop;
Fclient:=Tpanel.Create(Self);
with Fclient do
begin
setsubcomponent(true);
ControlStyle := ControlStyle + [csAcceptsControls];
Align:=alclient;
Parent:=self;
color:=clwhite;
BorderStyle:=bssingle;
Ctl3D:=false;
ParentCtl3D:=false;
Bevelouter:=bvnone;
end;
end;

destructor TtestControl.Destroy;
begin
FHeader.Free;
FClient.Free;
inherited;
end;

end.

如果我在测试组件上放置一个按钮,结构会将其显示为表单的一部分,而不是测试组件的子组件......然后它就不起作用了。

有办法做到这一点吗?

最佳答案

经过大量谷歌搜索后,我发现了一些信息,这些信息使我能够拼凑出一个似乎可行的解决方案。

似乎需要重写基类中的两个过程来更新控件。

第一个是名为“Loaded”的方法,该方法在流传输结束时调用。

流式传输似乎将设计者放置的所有子面板组件放置在基本组件上,而不是放置在它们最初父级的面板上。因此,此例程在加载过程完成后手动重新分配 Parent 属性。

第二种方法称为 GetChildren,除了 chm 帮助中相当神秘的文本之外,我找不到太多关于该方法实际用途的信息。不过,我从网上找到的另一个示例中改编了重写的代码,该示例具有类似的要求并且有效。因此,如果任何人都可以提供一些关于为什么这是必要的见解,那么这将是有用的信息。

我已经粘贴了下面示例自定义组件的完整源代码,以便将来有类似需求的任何人都可以将其用作自己组件的起始模板。

unit Testcontrol;

interface
uses Windows, System.Classes, Vcl.Controls, Vcl.Forms, Vcl.ExtCtrls,graphics;

type
TtestControl = class(TCustomControl)
private
FHeader:Tpanel;
FClient:Tpanel;
protected
procedure Loaded;override;
procedure GetChildren(Proc:TGetChildProc; Root:TComponent);override;
public
constructor Create(Aowner:Tcomponent);override;
destructor Destroy;override;
published
property Align;
end;

implementation

{ TtestControl }

constructor TtestControl.Create(Aowner:Tcomponent);
begin
inherited;
Fheader:=Tpanel.create(self);
Fheader.setsubcomponent(true);
Fheader.Caption:='Header';
Fheader.Height:=20;
Fheader.Parent:=self;
Fheader.Align:=altop;
Fclient:=Tpanel.Create(Self);
with Fclient do
begin
setsubcomponent(true);
ControlStyle := ControlStyle + [csAcceptsControls];
Align:=alclient;
Parent:=self;
color:=clwhite;
BorderStyle:=bssingle;
Ctl3D:=false;
ParentCtl3D:=false;
Bevelouter:=bvnone;
end;
end;

destructor TtestControl.Destroy;
begin
FHeader.Free;
FClient.Free;
inherited;
end;

procedure TtestControl.Loaded;
var i:integer;
begin
inherited;
for i := ControlCount - 1 downto 0 do
if (Controls[i] <> Fheader) and (Controls[i] <> Fclient) then
Controls[i].Parent := Fclient;
end;

procedure TtestControl.GetChildren(Proc:TGetChildProc; Root:TComponent);
var i:integer;
begin
inherited;
for i := 0 to Fclient.ControlCount-1 do
Proc(Fclient.Controls[i]);
end;

end.

关于delphi - 自定义控件中的子面板是否可以接受设计器的控件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54507778/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com