我有一个主表单,框架和数据模块的应用程序。 创建主窗体时,我还创建了一个框架,其中包含数据模块中表格中的字段。 所以主要的表单代码是:
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事件中框架中存在的过程被触发。有办法做到这一点吗?
答案 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
可以访问这些属性,而不必在框架的私有部分中查找。