问题:
当您将面板组件复制到剪贴板时,所有已发布的属性都被转换成文本(粘贴到记事本中查看其外观)。
将其粘贴到表单上会从此文本中重新构建组件。
由于Vcl.ExtCtrls.TGridPanel
中的ControlCollection
属性被定义为published
,因此其中的按钮也包括在此文本中。以下是一段摘录:
object MyGridPanel1: TMyGridPanel
Left = 64
...
ControlCollection = <
item
Column = 0
Control = Button9
Row = 0
end
item
Column = 1
Control = Button10
Row = 0
end
...
object Button9: TButton
Left = 1
...
end
object Button10: TButton
Left = 92
...
end
...
end
当粘贴时,IDE设计器首先创建一个
TMyGridPanel
类的新对象。在此步骤中,
TMyGridPanel
的构造函数会创建一组新的按钮。
之后,所有已发布的属性都从文本中重建,包括其中的ControlCollection和Buttons,这就是问题所在。
可能的解决方案:
在这种情况下,一个可能的解决方案是将
TMyGridPanel
的父类更改为
TCustomGridPanel
。
TMyGridPanel2 = class(TCustomGridPanel)
...
TCustomGridPanel
(类似其他TCustom...
组件)不会发布其任何属性,因此它们不会被流式传输到剪贴板。
实际上,从控件的TCustom...
变体继承,而不是从在组件面板中注册的变体继承,是子类化组件的正确方式。
如果现在将TMyGridPanel2
的这个变体复制到剪贴板并将其粘贴到记事本中,我们可以看到没有其他属性:
object MyGridPanel21: TMyGridPanel2
Left = 184
Top = 200
Width = 185
Height = 41
end
缺点:
这种方法可行,但有几个需要注意的缺点:
You cannot access custom properties introduced by TGridPanel
in Object Inspector (but you can access them at runtime).
A workaround to bring a property back in Object Inspector, is to add it in published
section of your component:
TMyGridPanel2 = class(TCustomGridPanel)
public
...
published
property BorderStyle;
property ColumnCollection;
property RowCollection;
...
end;
You cannot change properties of the four buttons via Object Inspector, nor attach events to them. You have to do that in code.
Actually this is good behavior. When you create a composite component that has child controls, it is good practice to have all functionality contained within the component itself.
完整代码示例:
unit MyGridPanel2;
interface
uses
Classes, Vcl.StdCtrls, Vcl.ExtCtrls, Vcl.Controls;
type
TMyGridPanel2 = class(TCustomGridPanel)
private
public
constructor Create(AOwner: TComponent); override;
published
end;
procedure Register;
implementation
constructor TMyGridPanel2.Create(AOwner: TComponent);
var
i: Integer;
btn: TButton;
begin
inherited Create(AOwner);
for i := 0 to 3 do
begin
btn := TButton.Create(Self);
btn.Parent := Self;
btn.Align := alClient;
btn.Caption := 'Hello World';
btn.Visible := True;
end;
end;
procedure Register;
begin
RegisterComponents('Custom', [TMyGridPanel2]);
end;
end.
首先在测试项目中尝试,而不是在生产环境中进行。