简体   繁体   中英

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

I am creating UI Components programmatically. One of my components is a TButton (or descendant), and I want the button to create an object of a given type when clicked. I have dozens of types and of course I don't want to create dozens of TxxxButton classes.

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?

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.

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. 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.

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. You can declare an OnCreateObject property in the button and assign a method to it, which constructs the object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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