Как переопределить FetchOptions.Mode для TxDataSet всегда использовать fmAll независимо от настроек в дизайнере Delphi? Delphi , Компоненты и Классы , TDBNavigator
В данной статье мы рассмотрим, как заставить свой кастомный компонент TxDataSet
(на основе TFDDataSet
из FireDAC) всегда использовать режим fmAll
для FetchOptions.Mode
, игнорируя настройки, заданные в дизайнере Delphi. Проблема, описанная пользователем WalkingAway, заключается в том, что несмотря на попытки установить FetchOptions.Mode = fmAll
в конструкторах, значение, заданное в DFM-файле (файле дизайна формы), переопределяет это изменение.
Проблема и решение, предложенное PeterBelow
Пользователь PeterBelow предложил использовать метод Loaded
компонента, чтобы переопределить значение FetchOptions.Mode
. Это связано с тем, что свойства компонента, помещенного на форму, загружаются из DFM-файла после выполнения конструктора. Таким образом, изменение значения в конструкторе может быть перезаписано при загрузке свойств из DFM.
Реализация решения с использованием метода Loaded
В Delphi, метод Loaded
вызывается после того, как компонент был загружен из DFM-файла и его свойства были инициализированы из этого файла. Это позволяет корректно переопределить свойства, которые были установлены в дизайнере.
Вот пример реализации:
unit xDataSet;
interface
uses
System.SysUtils, System.Classes, Data.DB,
FireDAC.Comp.DataSet,
Firedac.Stan.Def,
Firedac.Stan.Param,
Firedac.Stan.Option,
Firedac.DatS,
Firedac.Phys.Intf;
type
TxBaseDataSet = class(TFDDataSet)
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
{ TFDDataSet }
property FetchOptions;
property FormatOptions;
property ResourceOptions;
property SecurityOptions;
property UpdateOptions;
published
{ Published declarations }
end;
TxCustomDataSet = class(TxBaseDataSet)
private
FOptionsIntf: IFDStanOptions;
protected
FStoreDefs: Boolean;
property StoreDefs: Boolean read FStoreDefs write FStoreDefs default False;
// IFDStanOptions
function GetOptionsIntf: IFDStanOptions; override;
procedure GetParentOptions(var AOpts: IFDStanOptions);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
end;
TxDataSet = class(TxCustomDataSet)
published
property ActiveStoredUsage;
{ TDataSet }
property Active;
property AutoCalcFields;
property BeforeOpen;
property AfterOpen;
property BeforeClose;
property AfterClose;
property BeforeInsert;
property AfterInsert;
property BeforeEdit;
property AfterEdit;
property BeforePost;
property AfterPost;
property BeforeCancel;
property AfterCancel;
property BeforeDelete;
property AfterDelete;
property BeforeScroll;
property AfterScroll;
property BeforeRefresh;
property AfterRefresh;
property OnCalcFields;
property OnDeleteError;
property OnEditError;
property OnNewRecord;
property OnPostError;
property FieldOptions;
property Filtered;
property FilterOptions;
property Filter;
property OnFilterRecord;
property ObjectView default True;
property Constraints;
property DataSetField;
property FieldDefs stored FStoreDefs;
{ TFDDataSet }
property CachedUpdates;
property FilterChanges;
property IndexDefs stored FStoreDefs;
property Indexes;
property IndexesActive;
property IndexName;
property IndexFieldNames;
property Aggregates;
property AggregatesActive;
property ConstraintsEnabled;
property MasterSource;
property MasterFields;
property DetailFields;
property OnUpdateRecord;
property OnUpdateError;
property OnReconcileError;
property BeforeApplyUpdates;
property AfterApplyUpdates;
property BeforeGetRecords;
property AfterGetRecords;
property AfterGetRecord;
property BeforeRowRequest;
property AfterRowRequest;
property BeforeExecute;
property AfterExecute;
property FetchOptions;
property FormatOptions;
property ResourceOptions;
property SecurityOptions;
property UpdateOptions;
{ TxCustomCustomDataset }
property StoreDefs;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Samples', [TxDataSet]);
end;
{ TxBaseDataSet }
constructor TxBaseDataSet.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
end;
destructor TxBaseDataSet.Destroy;
begin
inherited Destroy;
end;
{ TxustomCustomDataset }
constructor TxCustomDataSet.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
end;
destructor TxCustomDataSet.Destroy;
begin
Close;
Destroying;
inherited Destroy;
if FOptionsIntf <> nil then begin
FOptionsIntf.ObjectDestroyed(Self);
FOptionsIntf := nil;
end;
end;
function TxCustomDataSet.GetOptionsIntf: IFDStanOptions;
begin
if FOptionsIntf = nil then
FOptionsIntf := TFDOptionsContainer.Create(Self, TFDFetchOptions,
TFDBottomUpdateOptions, TFDBottomResourceOptions, GetParentOptions);
Result := FOptionsIntf;
end;
procedure TxCustomDataSet.GetParentOptions(var AOpts: IFDStanOptions);
begin
AOpts := nil;
end;
{ TxDataSet }
constructor TxDataSet.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
end;
destructor TxDataSet.Destroy;
begin
inherited Destroy;
end;
procedure TxDataSet.Loaded;
begin
inherited;
FetchOptions.Mode := fmAll;
end;
end.
Альтернативное решение: Переопределение метода SetFetchOptions
Вместо использования Loaded
, можно переопределить метод SetFetchOptions
класса TFDDataSet
. Этот метод вызывается при изменении FetchOptions, и в нем можно установить Mode
в fmAll
. Этот подход может быть более эффективным, если необходимо, чтобы Mode
всегда был fmAll
при любых изменениях FetchOptions
.
unit xDataSet;
interface
uses
System.SysUtils, System.Classes, Data.DB,
FireDAC.Comp.DataSet,
Firedac.Stan.Def,
Firedac.Stan.Param,
Firedac.Stan.Option,
Firedac.DatS,
Firedac.Phys.Intf;
type
TxBaseDataSet = class(TFDDataSet)
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
{ TFDDataSet }
property FetchOptions;
property FormatOptions;
property ResourceOptions;
property SecurityOptions;
property UpdateOptions;
published
{ Published declarations }
end;
TxCustomDataSet = class(TxBaseDataSet)
private
FOptionsIntf: IFDStanOptions;
protected
FStoreDefs: Boolean;
procedure SetFetchOptions(Value: TFDStanFetchOptions); override;
property StoreDefs: Boolean read FStoreDefs write FStoreDefs default False;
// IFDStanOptions
function GetOptionsIntf: IFDStanOptions; override;
procedure GetParentOptions(var AOpts: IFDStanOptions);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
end;
TxDataSet = class(TxCustomDataSet)
published
property ActiveStoredUsage;
{ TDataSet }
property Active;
property AutoCalcFields;
property BeforeOpen;
property AfterOpen;
property BeforeClose;
property AfterClose;
property BeforeInsert;
property AfterInsert;
property BeforeEdit;
property AfterEdit;
property BeforePost;
property AfterPost;
property BeforeCancel;
property AfterCancel;
property BeforeDelete;
property AfterDelete;
property BeforeScroll;
property AfterScroll;
property BeforeRefresh;
property AfterRefresh;
property OnCalcFields;
property OnDeleteError;
property OnEditError;
property OnNewRecord;
property OnPostError;
property FieldOptions;
property Filtered;
property FilterOptions;
property Filter;
property OnFilterRecord;
property ObjectView default True;
property Constraints;
property DataSetField;
property FieldDefs stored FStoreDefs;
{ TFDDataSet }
property CachedUpdates;
property FilterChanges;
property IndexDefs stored FStoreDefs;
property Indexes;
property IndexesActive;
property IndexName;
property IndexFieldNames;
property Aggregates;
property AggregatesActive;
property ConstraintsEnabled;
property MasterSource;
property MasterFields;
property DetailFields;
property OnUpdateRecord;
property OnUpdateError;
property OnReconcileError;
property BeforeApplyUpdates;
property AfterApplyUpdates;
property BeforeGetRecords;
property AfterGetRecords;
property AfterGetRecord;
property BeforeRowRequest;
property AfterRowRequest;
property BeforeExecute;
property AfterExecute;
property FetchOptions;
property FormatOptions;
property ResourceOptions;
property SecurityOptions;
property UpdateOptions;
{ TxCustomCustomDataset }
property StoreDefs;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Samples', [TxDataSet]);
end;
{ TxBaseDataSet }
constructor TxBaseDataSet.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
end;
destructor TxBaseDataSet.Destroy;
begin
inherited Destroy;
end;
{ TxustomCustomDataset }
constructor TxCustomDataSet.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
end;
destructor TxCustomDataSet.Destroy;
begin
Close;
Destroying;
inherited Destroy;
if FOptionsIntf <> nil then begin
FOptionsIntf.ObjectDestroyed(Self);
FOptionsIntf := nil;
end;
end;
function TxCustomDataSet.GetOptionsIntf: IFDStanOptions;
begin
if FOptionsIntf = nil then
FOptionsIntf := TFDOptionsContainer.Create(Self, TFDFetchOptions,
TFDBottomUpdateOptions, TFDBottomResourceOptions, GetParentOptions);
Result := FOptionsIntf;
end;
procedure TxCustomDataSet.GetParentOptions(var AOpts: IFDStanOptions);
begin
AOpts := nil;
end;
{ TxDataSet }
constructor TxDataSet.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
end;
destructor TxDataSet.Destroy;
begin
inherited Destroy;
end;
procedure TxCustomDataSet.SetFetchOptions(Value: TFDStanFetchOptions);
begin
inherited;
Value.Mode := fmAll;
end;
end.
Вывод
Оба предложенных решения позволяют переопределить FetchOptions.Mode
и всегда устанавливать его в fmAll
, независимо от настроек в дизайнере Delphi. Использование Loaded
- более простой подход, а переопределение SetFetchOptions
- более эффективное, если требуется постоянный контроль над значением Mode
. Выбор конкретного решения зависит от ваших конкретных требований и предпочтений.
Создано по материалам из источника по ссылке .
В данной статье обсуждаются способы заставления кастомного компонента `TxDataSet` (на основе `TFDDataSet` из FireDAC) всегда использовать режим `fmAll` для `FetchOptions.Mode`, игнорируя настройки, заданные в дизайнере Delphi, с использованием метода `Lo
Комментарии и вопросы Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.
:: Главная :: TDBNavigator ::