【问题标题】:How to break up TPageControl tabs into seperate files in Delphi?如何在 Delphi 中将 PageControl 选项卡拆分为单独的文件?
【发布时间】:2014-07-19 15:01:48
【问题描述】:

我有一个 VCL 表单,上面有五个标签 TPageControl。每个TTabSheet 的内容都是相当不相关的,并且有很多单独的控件和处理逻辑......所以我想把它分解,以便更容易处理“只是那个选项卡”的代码。有一条像

//-------------------------- begin rules tab methods -------------------

只是不再切割它了。真的,我想我想以某种方式将每个选项卡放在一个单独的文件中。

目前我正在考虑为每个 TTabPage 创建一个 VCL 框架。如果我这样做了,我要么需要将所有帧加载到构造函数中的 TPageControl 中,要么在显示选项卡时加载。

这是一个好方法吗?为每个选项卡制作一个完整的 TForm 会更好吗?我应该继续将选项卡包装在 TPageControl 中,还是应该在动态加载内容时将其更改为 TTabControl?如果这是一个好方法,最好在启动时加载所有选项卡,还是每次显示选项卡时加载? (如果不是很明显,在大多数/所有情况下哪个更好,也许是优点/缺点)

【问题讨论】:

  • ps downvoters,如果您离开 cmets 解释为什么这是一个糟糕的问题,我真的很感激,这样我可以改进它或下次提出更好的问题
  • IMO,您的问题过于宽泛且基于意见。您在这里至少问了 5 个不同的问题,其中四个在要点中,第五个是“最好的方法是什么?”如果没有访问(和时间分析)实际来源就无法回答的问题,“最好的方法”是一个意见问题,即使这是可能的。
  • @FreeConsulting 看看我的回答;o)
  • @SirRufo,哦,也许我需要一副新眼镜 :-)

标签: delphi vcl tpagecontrol


【解决方案1】:

您可以使用框架或表单。

  • 对于 Frames,您必须添加一个 TabControl 作为每个 Frame 的父级。
  • 对于表单,您有 to dock 每个表单到 PageControl(表单标题将自动成为 TabControl 标题)。

procedure TMyForm.AddPage( AFormClass : TFormClass );
var
  LForm : TForm;
begin
  LForm := AFormClass.Create( Self );
  LForm.ManualDock( PageControl1, nil, alClient );
  LForm.Show;
end;

示例

创建基本设置表单

unit UI_Form_SettingBase;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs;

type
  TUISettingBase_Form = class( TForm )
  private

  protected
    procedure DoSaveData; virtual;
  public
    function CanSaveData : Boolean; virtual;
    procedure SaveData;
  end;

  TUISettingBase_FormClass = class of TUISettingBase_Form;

var
  UISettingBase_Form : TUISettingBase_Form;

implementation

{$R *.dfm}
{ TUISettingBase_Form }

function TUISettingBase_Form.CanSaveData : Boolean;
begin
  Result := True;
end;

procedure TUISettingBase_Form.DoSaveData;
begin

end;

procedure TUISettingBase_Form.SaveData;
begin
  if CanSaveData
  then
    DoSaveData;
end;

end.

从该表单派生所有设置表单并覆盖 DoSaveData 和可选的 CanSaveData 方法

通用设置(带有一个简单的复选框)

unit UI_Form_SettingCommon;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, UI_Form_SettingBase, Vcl.StdCtrls;

type
  TUISettingCommon_Form = class(TUISettingBase_Form)
    CheckBox1: TCheckBox;
  private

  protected
    procedure DoSaveData; override;
  public

  end;

var
  UISettingCommon_Form: TUISettingCommon_Form;

implementation

{$R *.dfm}

procedure TUISettingCommon_Form.DoSaveData;
begin
  inherited;
  // code to save the data
end;

end.

连接设置(带有简单的编辑控件)

unit UI_Form_SettingConnection;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, UI_Form_SettingBase, Vcl.StdCtrls;

type
  TUISettingConnection_Form = class( TUISettingBase_Form )
    Edit1 : TEdit;
  private
  protected
    procedure DoSaveData; override;
  public
  end;

var
  UISettingConnection_Form : TUISettingConnection_Form;

implementation

{$R *.dfm}
{ TUISettingConnection_Form }

procedure TUISettingConnection_Form.DoSaveData;
begin
  inherited;
  // code to save the data
end;

end.

拼凑:真正的设置表单

主要的Setting Form也来源于SettingBase

unit UI_Form_Settings;

interface

uses
  System.Generics.Collections,
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, UI_Form_SettingBase, Vcl.StdCtrls,
  Vcl.ExtCtrls, Vcl.ComCtrls;

type
  TUISettings_Form = class( TUISettingBase_Form )
    PageControl1 : TPageControl;
    Panel1 : TPanel;
    Save_Button : TButton;
  private
    FForms : TList<TUISettingBase_Form>;
    procedure AddSettingPage( ASettingFormClass : TUISettingBase_FormClass );
  protected
    procedure DoSaveData; override;
  public
    function CanSaveData : Boolean; override;
    procedure AfterConstruction; override;
    procedure BeforeDestruction; override;
  end;

var
  UISettings_Form : TUISettings_Form;

implementation

{$R *.dfm}

uses
  UI_Form_SettingCommon, UI_Form_SettingConnection;
{ TUISettings_Form }

procedure TUISettings_Form.AddSettingPage( ASettingFormClass : TUISettingBase_FormClass );
var
  LForm : TUISettingBase_Form;
begin
  LForm := ASettingFormClass.Create( Self );
  try
    LForm.ManualDock( PageControl1, nil, alClient );
    LForm.Show;
    FForms.Add( LForm );
    LForm := nil;
  finally
    LForm.Free;
  end;
end;

procedure TUISettings_Form.AfterConstruction;
begin
  inherited;
  FForms := TList<TUISettingBase_Form>.Create;
  // add all the setting forms
  AddSettingPage( TUISettingCommon_Form );
  AddSettingPage( TUISettingConnection_Form );
end;

procedure TUISettings_Form.BeforeDestruction;
begin
  inherited;
  FForms.Free;
end;

function TUISettings_Form.CanSaveData : Boolean;
var
  LForm : TUISettingBase_Form;
begin
  // iterate all setting forms if they can save the data
  Result := True;
  for LForm in FForms do
    Result := Result and LForm.CanSaveData;
end;

procedure TUISettings_Form.DoSaveData;
var
  LForm : TUISettingBase_Form;
begin
  inherited;
  // iterate all setting forms and save the data
  for LForm in FForms do
    LForm.SaveData;
end;

end.

【讨论】:

  • 显然你不能将 ActionManagers 添加到框架中,只能添加到表单中。因此,在这种情况下,这几乎解决了问题。感谢您提及这两种解决方案。
【解决方案2】:

我特别想做的一件事(这个问题的重点)是以某种方式分解包含五个 TTabSheets 的 TPageControl。每个选项卡表都是 UI(以及相应的处理逻辑)的一个非常紧密的部分,因此最好将每个选项卡分成单独的文件。

您可以为此使用TFrame。为每个页面提供自己的框架,您可以使用自己的 DFM 在各自的文件中实施和设计。

对于每个分解的选项卡,我是否要从添加新的 VCL 表单开始?还是 VCL 框架?

帧。不要使用嵌入式表单,它们效果不佳。框架就是为此目的而设计的。

如果每个选项卡的内容都是从面板加载的,我应该离开 TPageControl 还是将其更改为 TTabControl?

创建新框架并根据需要对其进行设计后,您可以:

  1. 将框架放在组件调色板上(在设计器中右键单击框架并选择“添加到调色板”),然后您可以在设计时将其拖放到所需的TTabSheet 上。如果您希望 Frame 的 Align 填满整个 TTabSheet,请将其设置为 alClient

  2. 在运行时在代码中实例化 Frame 对象,然后将其 Parent 属性设置为所需的 TTabSheet

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-07
    • 1970-01-01
    相关资源
    最近更新 更多