简体   繁体   English

Delphi-创建一个通用的TButton来创建任何给定类的对象

[英]Delphi - Creating a generic TButton that creates an object of any given class

I am creating UI Components programmatically. 我正在以编程方式创建UI组件。 One of my components is a TButton (or descendant), and I want the button to create an object of a given type when clicked. 我的组件之一是TButton(或后代),并且我希望按钮在单击时创建给定类型的对象。 I have dozens of types and of course I don't want to create dozens of TxxxButton classes. 我有很多类型,当然我也不想创建很多TxxxButton类。

Is it possible to have a single generic TButton descendant, and for example add a property which holds a class and tell it that whenever clicked, it should add one object of such a class? 是否可以有一个单一的通用TButton后代,例如添加一个保存类的属性,并告诉它每当单击该按钮时,就应该添加一个此类的对象?

TCustomButton = class(TButton)
  public
    childObjectType: TClass;
    procedure Click; override;
...

then i want to do 那我想做

TCustomButton.Create;
TCustomButton.childObjectType:=TClass1;

and as a result, when I click any such button, it will create an object of type TClass1. 结果,当我单击任何此类按钮时,它将创建一个TClass1类型的对象。

Should I look at generics? 我应该看看泛型吗?

Thanks for any insight. 感谢您的见解。

I don't think generic VCL components would be the right approach here, but you can give the button a class type. 我认为通用的VCL组件在这里不是正确的方法,但是您可以为按钮指定类类型。 Especially if the object you want to create is a TComponent descendant, which typically has the same constructor, you can just create it like that. 特别是如果您要创建的对象是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;

For more fine-grained control, for instance if it can be any class and therefore any constructor signature, you could pass a factory method or a factory object to your button. 对于更细粒度的控件,例如,如果它可以是任何类,因此可以是任何构造函数签名,则可以将工厂方法或工厂对象传递给按钮。 The factory object has a fixed interface which the button can call, and does all the work for rigging up the object. 该工厂对象具有一个固定的接口,该按钮可以调用该接口,并完成装配该对象的所有工作。 That way, any complexities in creating the object can be hidden away in the factory, and the button doesn't need to know about it. 这样,创建对象的任何复杂性都可以在工厂中隐藏起来,并且按钮不需要知道它。

The factory itself doesn't need to be a visual component, and it's somewhat easier to use generics for it, if you want to, although it doesn't seem to be very useful in this scenario. 工厂本身不需要成为可视组件,并且如果需要,可以使用泛型来简化操作,尽管在这种情况下它似乎不是很有用。

In one of the simplest forms, you can just pass a procedure or function to the button which it can call to create the object. 在最简单的形式之一中,您只需将过程或函数传递给按钮即可调用以创建对象。 This can be implemented in the same way as an event like OnClick. 可以通过与OnClick之类的事件相同的方式来实现。 You can declare an OnCreateObject property in the button and assign a method to it, which constructs the object. 您可以在按钮中声明一个OnCreateObject属性,并为其分配一个方法,该方法构造该对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM