数据模块中的Delphi火帧事件



我有一个由主窗体、框架和数据模块组成的应用程序。当创建主表单时,我还创建了包含数据模块中表中字段的框架。所以主要的表单代码是:

unit main;
interface
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  FraDtl;
type
  TfrmMain = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    FFraDtl: TfraDetail;
  public
    { Public declarations }
  end;
var
  frmMain: TfrmMain;
implementation
{$R *.dfm}
procedure TfrmMain.FormCreate(Sender: TObject);
begin
  FFraDtl := TfraDetail.Create(Self);
  FFraDtl.Parent := Self;
end;
end.

帧的代码是这样的:

unit FraDtl;
interface
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  database, cxGraphics, cxControls, cxLookAndFeels, cxLookAndFeelPainters,
  cxContainer, cxEdit, cxTextEdit, cxDBEdit, Vcl.StdCtrls, dxSkinsCore,
  cxNavigator, cxDBNavigator;
type
  TfraDetail = class(TFrame)
    lblCognome: TLabel;
    edtCognome: TcxDBTextEdit;
    lblNome: TLabel;
    edtNome: TcxDBTextEdit;
    cxDBNavigator1: TcxDBNavigator;
  private
    { Private declarations }
  public
    { Public declarations }
  end;
implementation
{$R *.dfm}
end.

数据模块的代码是:

unit database;
interface
uses
  System.SysUtils, System.Classes, Data.DB, DBAccess, MSAccess, MemDS,
  dxSkinsCore, cxClasses, cxLookAndFeels, dxSkinsForm;
type
  TdmData = class(TDataModule)
    Connection: TMSConnection;
    tblAutori: TMSTable;
    dsAutori: TMSDataSource;
    fAut_IdAutore: TIntegerField;
    fAut_Cognome: TStringField;
    fAut_Nome: TStringField;
    fAut_Nominativo: TStringField;
    SkinController: TdxSkinController;
    procedure DataModuleCreate(Sender: TObject);
    procedure DataModuleDestroy(Sender: TObject);
    procedure dsAutoriStateChange(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  dmData: TdmData;
implementation
{$R *.dfm}
procedure TdmData.DataModuleCreate(Sender: TObject);
begin
  tblAutori.Open;
end;
procedure TdmData.DataModuleDestroy(Sender: TObject);
begin
  tblAutori.Close;
end;
procedure TdmData.dsAutoriStateChange(Sender: TObject);
begin
  // Some stuff
end;
end.

我想调用dsAutoriStateChange事件被激发时帧中存在的过程。有办法做到这一点吗?

我想调用dsAutoriStateChange事件被激发时帧中存在的过程。

你可以使用这样的代码:

unit database;
....
implementation
uses FraDtl;
procedure TdmData.dsAutoriStateChange(Sender: TObject);
begin
  FraDtl.SomeProcedure; 
end;

或者,如果你想访问实际的实例化框架,你可以访问主单元。

unit database;
....
implementation
uses main;  //circular reference allowed in implementation
procedure TdmData.dsAutoriStateChange(Sender: TObject);
begin
  frmMain.FrameDetail.DoSomething(Sender); 
end;

在这种情况下,您需要向frmMain添加一个公开框架的公共属性。

TfrmMain = class(TForm)
...
public
  property FrameDetail: TFraDetail read FFraDtl;

警告
数据模块和表单之间的这种硬耦合被认为是糟糕的编程实践
松耦合良好
硬耦合是糟糕的

最好对主窗体内的数据源使用事件处理程序,或者如果无法向TdmData添加由主窗体根据需要更新的其他属性,则使用事件处理器
事件处理程序dsAutoriStateChange然后可以访问这些属性,而不必在帧的私有部分中四处走动。

最新更新