Как разбить вкладки TPageControl на отдельные файлы в Delphi?
у меня есть форма VCL с пятью вкладками TPageControl
на нем. Каждый довольно несвязано и имеет много отдельных элементов управления и логики обработки...поэтому я хочу разбить его, чтобы легче было иметь дело с кодом для "только этой вкладки". Имея строку типа
//-------------------------- begin rules tab methods -------------------
просто больше не режет. Действительно, я думаю, что мне бы понравилась каждая вкладка в отдельном файле.
В настоящее время я рассматриваю создание фрейма VCL для каждой страницы TTabPage. Если бы я это сделал, я бы тоже необходимо загрузить все кадры в TPageControl в конструкторе или при отображении вкладки.
это хороший подход? Было бы лучше сделать целую TForm для каждой вкладки? Должен ли я продолжать обертывать вкладки в TPageControl, или это должно быть изменено на TTabControl, если содержимое загружается динамически? Если это хороший подход, лучше загружать все вкладки при запуске, или каждый раз, когда вкладка отображается? (возможно, плюсы/минусы, если это не совсем очевидно, что лучше в большинстве / всех случаев)
2 ответов
вы можете использовать фреймы или формы.
- С кадрами вы должны добавить TabControl в качестве родителя для каждого кадра.
- С формами у вас есть док каждая форма в 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.
сложение частей вместе: реальная форма настройки
основная форма настройки также является производной от 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.
одна вещь, в частности, которую я хотел бы сделать (фокус этого вопроса), - это каким-то образом разбить TPageControl, содержащий пять таблиц TTabSheets. Каждая вкладка представляет собой довольно сплоченный раздел пользовательского интерфейса (и соответствующую логику обработки), поэтому было бы неплохо разбить каждую вкладку на отдельные файлы.
можно использовать TFrame
для этого. Дайте каждой странице свой собственный фрейм, который вы можете реализовать и спроектировать в своих отдельных файлах со своими DFMs.
для каждой разбитой вкладки я хотел бы начать с добавления новых форм VCL? или VCL кадров?
кадров. Не используйте встроенные формы, они не очень хорошо работают. Для этой цели были разработаны рамы.
должен ли я оставить TPageControl или изменить его на TTabControl, если содержимое каждой вкладки загружается с панели?
после того как вы создаете новую рамку и конструируете ее по мере необходимости, вы можете после этого либо:
поместите рамку на палитру компонентов (щелкните правой кнопкой мыши на рамке в конструкторе и выберите "Добавить в палитру"), а затем вы можете поместить ее на нужную
TTabSheet
во время разработки. Установите кадрAlign
toalClient
Если вы хотите, чтобы заполнить весьTTabSheet
.создайте экземпляр объекта Frame в коде во время выполнения, а затем установите его
Parent
свойства нужногоTTabSheet
.