我编写了一个自定义控件,它有几个子面板。我希望这些子面板能够接受在设计时丢弃的任何其他控件。
不幸的是,任何在设计时被删除的控件都会在我的自定义控件上出现,而不是在面板上。这特别显示了我是否尝试删除标签:标签的蓝点显示,但标题不是,如果我取消选择标签,它就不再可见了。
简化代码(只有一个子面板):
type
TMyContainer = class(TPanel)
p_SubPanel: TPanel;
public
constructor Create(_Owner: TComponent); override;
end;
constructor TMyContainer.Create(_Owner: TComponent);
begin
inherited;
p_SubPanel := TPanel.Create(Self);
p_SubPanel.Parent := Self;
p_SubPanel.Align := alClient;
end;
我在这里做错了什么?
(以防万一重要:我使用的是Delphi 2007。)
[编辑]
我现在以不同的方式解决了它。该组件不再包含面板,但指的是外部面板。这使得它实际上更加灵活,但在不利方面,它不再直观易用。
我仍然想知道如何完成我原先描述的内容。是不是有一个开源组件可以做到这一点,所以我可以研究源代码?
答案 0 :(得分:2)
这是一个很好的问题。通过将csAcceptControls添加到控件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;
使用该代码,您现在可以将控件拖放到子面板上,但这意味着您还可以选择子面板,更改其属性,甚至删除您肯定不想要的属性。对不起,我无法想出答案,我仍然很想知道你是否解决了这个问题。 :)
答案 1 :(得分:1)
我无法从详细信息中了解到,但您是否将标签的父级设置为子面板?如果在设计时你可能需要在主要组件中编写代码(例如,面板所在的容器),要确定哪个子面板正在接受该组件,并将标签父属性设置为该子面板。
我非常确定在添加或从其他组件中删除组件时会调用通知方法,这可以帮助您找到放置代码所需的位置。
答案 2 :(得分:0)
我这样做了,但最终用常规面板替换了控件,这些面板会在需要时显示/隐藏。
而不是从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;