delphivcltpagecontrol

How to break up TPageControl tabs into seperate files in Delphi?


I have a VCL form with a five tab TPageControl on it. Each TTabSheet's content is fairly unrelated and has a lot of individual controls and processing logic...so I want to break it up so it's easier to deal with the code for "just that tab". Having a line like

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

just isn't cutting it anymore. Really, I think I'd like each tab in a separate file somehow.

Currently I'm contemplating creating a VCL Frame for each TTabPage. If I did so I'd either need to load all the frames into the TPageControl in the constructor, or when the tab is shown.

Is this a good approach? Would it be better to make a whole TForm for each tab? Should I continue to wrap the tabs in a TPageControl, or should that be changed to a TTabControl if the content is loaded dynamically? If this is a good approach, is it better to load all the tabs on startup, or each time the tab is shown? (perhaps pros/cons if it's not totally obvious which is better in most/all cases)


Solution

  • You can use either Frames or Forms.


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

    Example

    Create a base Settings Form

    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.
    

    Derive all Settings Forms from that Form and override the DoSaveData and optionally the CanSaveData methods

    Common Settings (with a simple CheckBox)

    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.
    

    Connection Settings (with a simple Edit control)

    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.
    

    Putting the pieces together: The real Settings Form

    The main Setting Form is also derived from the 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.