Delphi来自datamodule的火帧事件

时间:2016-04-29 12:41:48

标签: delphi events frame

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

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事件中框架中存在的过程被触发。有办法做到这一点吗?

1 个答案:

答案 0 :(得分:1)

  

我想调用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;

警告
数据模块和表单之间的这种硬耦合被认为是糟糕的编程实践 Loose coupling is good
Hard coupling is bad

最好在mainform中使用数据源的事件处理程序,或者如果无法向TdmData添加根据需要由主表单更新的其他属性。
/> 然后,事件处理程序dsAutoriStateChange可以访问这些属性,而不必在框架的私有部分中查找。