我将TGridPanel
子类化为我的控件TMyGridPanel
。
我这样做是因为我想在GridPanel
中添加4个默认按钮。
所以我覆盖constructor
并创建如下按钮:
constructor TMyGridPanel.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;
这很好用。
ControlCollection
Items属性显示4个按钮为CollectionItems
。
现在我想要复制并粘贴(复制)我的控件,因为我想要有2个。 但是,当我这样做时,按钮不会显示在控件中。
ControlCollection
Items属性显示4个Collection Items但它们没有名称(空)。
当我关闭表格并重新打开时,按钮出现。
我正试图解决这个问题已经有好几天但是无法弄明白。
答案 0 :(得分:3)
将面板组件复制到剪贴板时,其所有已发布的属性都会流式传输到文本中(将其粘贴到记事本中以查看其外观)。
粘贴到表单会从此文本重新构建组件。
由于Vcl.ExtCtrls.TGridPanel
属性在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
,因此其中的按钮包含在此文本中。这是一段摘录:
TMyGridPanel
粘贴时,IDE设计者首先创建一个类TMyGridPanel
的新对象。在此步骤中,TMyGridPanel
的构造函数会创建一组新按钮。
之后,所有已发布的属性都会从文本中重建,包括其中的ControlCollection和Buttons,这就是问题所在。
在这种情况下,可能的解决方案是将TCustomGridPanel
的父类更改为TMyGridPanel2 = class(TCustomGridPanel)
...
TCustomGridPanel
TCustom...
(与其他TCustom...
组件类似)不会发布任何属性,因此不会将其流式传输到剪贴板。
实际上从控件的TMyGridPanel2
变体继承,而不是从Component Pallet中注册的变量继承,是子组件的正确方法。
如果我们现在将object MyGridPanel21: TMyGridPanel2
Left = 184
Top = 200
Width = 185
Height = 41
end
的此变体复制到剪贴板并将其粘贴到记事本中,我们可以看到没有其他属性:
TGridPanel
这种方法有效,但有几个缺点需要注意:
您无法访问Object Inspector中published
引入的自定义属性(但您可以在运行时访问它们)。
将属性带回Object Inspector的解决方法是将其添加到组件的TMyGridPanel2 = class(TCustomGridPanel)
public
...
published
property BorderStyle;
property ColumnCollection;
property RowCollection;
...
end;
部分中:
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
{ TMyGridPanel2 }
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.
您无法通过Object Inspector更改四个按钮的属性,也不能将事件附加到它们。你必须在代码中这样做。
实际上这是好行为。当您创建具有子控件的复合组件时,最好将所有功能都包含在组件本身中。
let menuItem = NSMenuItem()
menuItem.title = object.name!
menuItem.keyEquivalent = object.shortcut!
menuItem.representedObject = object
menuItem.action = "testSelector:"
appDel.menu.insertItem(menuItem, atIndex: 0)
func testSelector(sender: NSMenuItem) {
let object = (sender.representedObject as! MyNewObject)
print("Name of set:", object.name)
}
首先在测试项目中尝试此操作,而不是在生产中。