【问题标题】:How to Create MDI Child of different type with Generics?如何使用泛型创建不同类型的 MDI 子项?
【发布时间】:2020-05-30 16:13:11
【问题描述】:

我需要将 MDI 子窗体的创建集中到 Delphi (VCL) 中的一个独特的过程中。这个想法是在每次创建 MDI 子窗体时执行一些操作,无论其类型如何,即将其标题名称添加到列表中以访问该 MDI 子窗体。像这样:

   procedure TMainForm<T>.CreateMDIChild(const ACaption : String);
    var
      Child: T;
    begin
      { create a new MDI child window }
      Child := T.Create(Application);
      Child.Caption := ACaption;
      // add this child to the list of active MDI windows
      ...
    end;

   procedure TMainForm.Button1Click(Sender : TObject);
   begin
       CreateMDIChild<TMdiChild1>('Child type 1');
       CreateMDIChild<TMdiChild2>('Child type 2');
       ...

但是,我没有使用泛型的经验。任何帮助我都会很感激。 非常感谢。

【问题讨论】:

  • 我假设你已经阅读了the documentation?
  • 你不能在表单类中使用泛型。
  • @DelphiCoder 是的,你可以
  • 是的,我阅读了文档,但我做错了 =( 并且是我第一次尝试使用泛型,所以我对这种方法没有经验。

标签: delphi generics vcl mdi


【解决方案1】:

您可以使用这样的类约束来定义一个用于通用创建表单的类(使用泛型):

TGenericMDIForm <T:TForm> = class
  class procedure CreateMDIChild(const Name: string);
end;

通过这个实现:

class procedure TGenericMDIForm<T>.CreateMDIChild(const Name: string);
var
  Child:TCustomForm;
begin
  Child := T.Create(Application);
  Child.Caption := Name + ' of ' + T.ClassName + ' class';
end;

现在,您可以使用它来创建 MDIChil 表单不同的类:

procedure TMainForm.Button1Click(Sender: TObject);
begin
   TGenericMDIForm<TMdiChild>.CreateMDIChild('Child type 1');
   TGenericMDIForm<TMdiChild2>.CreateMDIChild('Child type 2');
end; 

将class constraint 与通用TGenericMDIForm &lt;T:TForm&gt; = class 一起使用,您可以避免有人尝试将类似TGenericMDIForm&lt;TMemo&gt;.CreateMDIChild('Child type 1'); 的类与不是TForm 后代的类一起使用。

【讨论】:

    【解决方案2】:

    您可以使用单元 System.Generics.Collections 中的类。例如,为了解决类似的任务,我使用TObjectList&lt;TfmMDIChild&gt;,其中TfmMDIChild 我自己的班级。 另一个有用的提示是,您可以根据TObjectList 创建自己的收藏类。 我做了这样的事情:

      TWindowList = class(TObjectList<TfmMDIChild>)
      public
        procedure RefreshGrids;
        function FindWindow(const AClassName: string; AObjCode: Integer = 0): TfmMDIChild;
        procedure RefreshWindow(const AClassName: string; AObjForRefresh: integer = 0; AObjCode: Integer = 0);
        procedure RefreshToolBars;
      end;
    

    【讨论】:

    • 好的 Anton,您的解决方案非常有趣,我是泛型新手,我认为这种方法将来会非常有用。提前谢谢你=)
    猜你喜欢
    • 2022-10-15
    • 1970-01-01
    • 2021-10-10
    • 2022-11-02
    • 2021-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多