1

我们有一个应用程序,它在表单上有许多组件(面板、选项卡、编辑、组合框等......)。但是根据用户配置文件,它们中的大多数可以自动填充和/或不可见。因此,用户可以更快地完成工作。

问题:有没有更简单的方法在运行时创建、定位、更改所有权等?我想为给定单元创建 2 个 .dfm 文件,然后告诉应用程序使用什么 .dfm。喜欢:“嘿!用户是高级用户,请使用 Unit1Advanced.dfm!” 一个工作的例子会很好。我也想在 Delphi 7 中使用它,但它至少必须在 Delphi XE 中工作。

我所知道的存在到现在:

  1. ComponentsToCodeGExperts的函数可以从给定组件创建代码,正如 gabr 在此答案中指出的那样。
  2. 我可以创建 2 个表单并在运行时创建所需的一个。但这意味着每个附加的 .dfm 文件都有一个附加的 .pas 文件。这将更难维护。
  3. 这个答案似乎给出了一个提示。但我不习惯 TReader 和 TWriter 类......
4

4 回答 4

4

我可以根据你的第2点给你一个解决方案:从没有经验的用户的表单开始,根据需要放置所有控件并在pas文件中实现必要的代码。然后制作一个继承自第一个表单的新表单,并根据有经验的用户的需求对其进行调整。如有必要,您还可以添加一些实现。

一种更灵活的方法可能是从一个共同的锚点继承这两种形式。该方案的实际实施很大程度上取决于您的情况。

于 2011-12-10T13:37:00.793 回答
3

您希望多个 .dfm 文件只有一个 .pas 文件几乎不可能,但也有点难以理解:代码将仅限于不太高级的形式 可能,但真的不推荐

关于您的分离要求:

  • 创建:进行两个设计,并像Uwe提到的那样通过Visual Form Inheritance (VFI)执行此操作,因此您没有分离维护问题。
  • 位置和尺寸:这是一个非常糟糕的主意。让每个用户的控件保持在同一个位置。用户可能会获得高级权限,并被陌生的安排吓到。我要提出的唯一例外是表格的最小尺寸:高级版本可能更高和/或更宽。
  • 更改所有权:是的,我理解您的意思,但是控件不属于用户,也不应该属于用户。实现某种控制器来处理应该创建什么类型的表单。

Visible如果VFI不是一个选项,那么我建议你只设计高级表单,并通过设置链接操作的属性来控制高级控件的隐藏。Advanced: Boolean在应该存在的属性的设置器中或通过设置器执行此操作。或者将所有高级控件组合在一个或多个容器上:组合框、面板或框架,如 LU RD 注释。然后只需设置该容器的可见性。当前滚动条会相应地自动调整或消失。请注意,您仍然可以处理这些控件,即使您不想这样做。

于 2011-12-10T17:47:16.350 回答
2

警告:此答案是为了问题的完整性,仅用于实验目的。它永远不应该在现实世界的场景中使用。

您只需要一个源代码文件的两个单独的表单定义文件。

关键是利用CreateNew构造函数。引用它的文档:

使用 CreateNew 而不是 Create 创建表单,而不使用关联的 .DFM 文件对其进行初始化。

  1. 首先,编写您的高级表单:

    unit Advanced;
    
    interface
    
    uses
      Classes, Controls, Forms, StdCtrls;
    
    type
      TAdvancedForm = class(TForm)
        StandardGroupBox: TGroupBox;
          StandardButton: TButton;
        AdvancedGroupBox: TGroupBox;
          AdvancedButton: TButton;
        procedure StandardButtonClick(Sender: TObject);
        procedure AdvancedButtonClick(Sender: TObject);
      end;
    
    implementation
    
    {$R *.dfm}
    
    procedure TAdvancedForm.StandardButtonClick(Sender: TObject);
    begin
      Caption := Caption + ' Button1Click';
    end;
    
    procedure TAdvancedForm.AdvancedButtonClick(Sender: TObject);
    begin
      Caption := Caption + ' Button2Click';
    end;
    
    end.
    
  2. 构建您的应用程序,然后复制Advanced.dfmStandard.dfm.

  3. 在文本编辑器中打开Standard.dfm并删除高级组件(在本例中是包含按钮的高级组框),并将表单和表单类型重命名为(T)StandardForm

    object StandardForm: TStandardForm
      ...
      object StandardGroupBox: TGroupBox
        ...
        object StandardButton: TButton
          ...
        end
      end
    end
    
  4. 将标准表单的资源添加到Advanced.pas

    {$R *.dfm}
    {$R Standard.dfm}
    
  5. 现在使用以下代码,您可以打开同一个源文件的两个表单定义:

    uses
      Advanced;
    
    procedure TForm1.OpenAdvancedFormClick(Sender: TObject);
    var
      Form: TAdvancedForm;
    begin
      Form := TAdvancedForm.Create(Application);
      Form.Show;
    end;
    
    procedure TForm1.OpenStandardFormClick(Sender: TObject);
    var
    {
      Form: TAdvancedForm; // This is tricky! The form we are about to create has
                           // no AdvancedGroupBox nor AdvancedButton, so make sure
                           // you are not calling it with code completion.
      Form: TStandardForm; // Compiler has no knowledge of TStandardForm!
    }
      Form: TForm;         // So declare your form as TForm!
    begin
      // But create it as TAdvancedForm, otherwise components will not be found!
      Form := TAdvancedForm.CreateNew(Application);
      ReadComponentRes('TStandardForm', Form);
      Form.Show;
    end;
    
于 2011-12-13T00:23:28.050 回答
0

DevExpress ExpressLayout 组件可能会有所帮助 - 请参阅http://devexpress.com/Products/VCL/ExLayoutControl/

他们提供运行时表单定制 - 运行时控件定制 - 屏幕分辨率独立性等等

于 2011-12-10T13:28:06.193 回答