8

5 つのタブがある VCL フォームがありますTPageControl。それぞれTTabSheetのコンテンツはかなり関連性がなく、個別のコントロールと処理ロジックがたくさんあります...そのため、「そのタブだけ」のコードを扱いやすくするために分割したいと思います。のような行を持つ

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

もうそれをカットしていません。本当に、どうにかして各タブを別のファイルに入れたいと思います。

現在、TTabPage ごとに VCL フレームを作成することを検討しています。その場合、すべてのフレームをコンストラクターの TPageControl にロードするか、タブが表示されたときにロードする必要があります。

これは良いアプローチですか?タブごとに TForm 全体を作成したほうがよいでしょうか? TPageControl でタブをラップし続ける必要がありますか、それともコンテンツが動的に読み込まれる場合は TTabControl に変更する必要がありますか? これが良いアプローチである場合、起動時にすべてのタブをロードする方が良いですか、それともタブが表示されるたびにロードする方が良いですか? (ほとんど/すべての場合にどちらが優れているかが完全に明らかでない場合、おそらく長所/短所)

4

2 に答える 2

8

フレームまたはフォームのいずれかを使用できます。


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.

ピースをまとめる: 実際の設定フォーム

メインの設定フォームも 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.
于 2014-05-30T05:32:14.713 に答える
8

特にやりたいことの 1 つ (この質問の焦点) は、5 つの TTabSheets を含む TPageControl を何らかの方法で分割することです。各タブ シートは、UI (および対応する処理ロジック) のまとまりのあるセクションであるため、各タブを個別のファイルに分割すると便利です。

そのために使えますTFrame。各ページに独自のフレームを与えます。これは、独自の DFM を使用して独自の個別ファイルに実装および設計できます。

分割されたタブごとに、新しい VCL フォームを追加することから始めますか? またはVCLフレーム?

フレーム。埋め込みフォームは使用しないでください。うまく機能しません。フレームはその目的のために設計されました。

各タブのコンテンツがパネルからロードされている場合、TPageControl をそのままにするか、TTabControl に変更する必要がありますか?

新しいフレームを作成し、必要に応じてデザインしたら、次のいずれかを実行できます。

  1. フレームをコンポーネント パレットに配置すると (デザイナーでフレームを右クリックし、[パレットに追加] を選択します)、TTabSheet設計時に必要な場所にドロップできます。フレーム全体を埋める場合は、フレームAlignを に設定します。alClientTTabSheet

  2. 実行時にコード内で Frame オブジェクトをインスタンス化し、そのParentプロパティを目的の に設定しますTTabSheet

于 2014-05-30T01:25:04.430 に答える