Delphi - Создание универсального TButton, который создает объект любого данного класса
Я создаю компоненты пользовательского интерфейса программно. Одним из моих компонентов является TButton (или его потомок), и я хочу, чтобы кнопка создавала объект заданного типа при нажатии. У меня есть десятки типов и, конечно, я не хочу создавать десятки классов TxxxButton.
Можно ли иметь одного общего потомка TButton и, например, добавить свойство, которое содержит класс, и сообщить ему, что при щелчке он должен добавить один объект такого класса?
TCustomButton = class(TButton)
public
childObjectType: TClass;
procedure Click; override;
...
тогда я хочу сделать
TCustomButton.Create;
TCustomButton.childObjectType:=TClass1;
и в результате, когда я нажимаю любую такую кнопку, она создает объект типа TClass1.
Стоит ли смотреть на дженерики?
Спасибо за понимание.
1 ответ
Я не думаю, что общие компоненты VCL были бы правильным подходом, но вы можете присвоить кнопке тип класса. Особенно, если объект, который вы хотите создать, является потомком TComponent, который обычно имеет тот же конструктор, вы можете просто создать его таким образом.
type
TYourButton = class(TButton)
...
public
property ComponentClass: TComponentClass read ComponentClass write FComponentClass;
end;
procedure TYourButton.Click;
var
c: TComponent;
begin
c := ComponentClass.Create(Self);
// Rigging up c, for instance setting text, tag, or check if it's
// a TControl and set parent and position if so.
end;
// And to assign a component class:
YourButton1.ComponentClass := TPanel;
Для более детального управления, например, если это может быть любой класс и, следовательно, любая сигнатура конструктора, вы можете передать фабричный метод или фабричный объект своей кнопке. Заводской объект имеет фиксированный интерфейс, который может вызывать кнопка, и выполняет всю работу по установке объекта. Таким образом, любые сложности в создании объекта могут быть скрыты на фабрике, и кнопка не должна знать об этом.
Сама фабрика не должна быть визуальным компонентом, и для нее несколько проще использовать дженерики, если хотите, хотя в этом сценарии она не кажется очень полезной.
В одной из самых простых форм вы можете просто передать процедуру или функцию кнопке, которую она может вызвать для создания объекта. Это может быть реализовано так же, как событие, как OnClick. Вы можете объявить свойство OnCreateObject в кнопке и назначить ему метод, который создает объект.