如何在运行时分配 TFDMemtable AfterPost 和 AfterDelete 事件?
How to assign TFDMemtable AfterPost and AfterDelete events on runtime?
我有一个由多个表单共享的 DataModule,我在其中构建了一个过程来处理作为参数传递的 TFDMemtable。为了处理它,我必须禁用事件 AfterPost 和 AfterDelete,并且在结束处理时我必须重新启用它们。我没有成功启用它们,因为我无法以 "actualnameAfterpost".
的形式获取这些事件的实际名称
我试过了:
pMemTable.AfterPost := @pMemTable.AfterPost ; // Result ==> compile error
pMemTable.AfterPost := addr(pMemTable.AfterPost) ; // Result ==> compile error
pMemTable.AfterPost := MethodAddress(Pmemtable.ClassName +'AfterPost'); //
Result ==> compile error
这是主要代码:
procedure UpdateMemtable (var pMemTable : TFDmemtable);
begin
pMemTable.AfterPost := nil;
pMemTable.AfterDelete := nil;
TRY
with pMemTable do
begin
{ code to process pMemtable }
end;
FINALLY
pMemTable.AfterPost := ["actualmemtablenameAfterPost" ??];
pMemTable.AfterDelete := ["actualmemtablenameAfterDelete" ??];
END;
end;
谢谢大家!
您只需要编写您的程序,然后将它们分配为
...
private
{ Private declarations }
procedure MyAfterPost(ADataSet: TDataSet);
procedure MyAfterDelete(ADataSet: TDataSet);
...
procedure TForm1.MyAfterDelete(ADataSet: TDataSet);
begin
ShowMessage('After Delete Fired');
end;
procedure TForm1.MyAfterPost(ADataSet: TDataSet);
begin
ShowMessage('After Post Fired');
end;
....
pMemTable.AfterPost:= MyAfterPost;
pMemTable.AfterDelete:= MyAfterDelete;
这里有一个简单的示例可以帮助您理解,只需 运行 看看会发生什么
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, FireDAC.Stan.Intf, FireDAC.Stan.Option,
FireDAC.Stan.Param, FireDAC.Stan.Error, FireDAC.DatS, FireDAC.Phys.Intf,
FireDAC.DApt.Intf, Data.DB, FireDAC.Comp.DataSet, FireDAC.Comp.Client,
Vcl.ExtCtrls, Vcl.DBCtrls, Vcl.Grids, Vcl.DBGrids;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
pMemTable: TFDMemTable;
Ds: TDataSource;
Grid: TDBGrid;
Navigator: TDBNavigator;
procedure MyAfterPost(ADataSet: TDataSet);
procedure MyAfterDelete(ADataSet: TDataSet);
procedure GridTitleClick(Column: TColumn);
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
// Free all
pMemTable.Free;
Ds.Free;
Navigator.Free;
Grid.Free;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
// Create the pMemTable
pMemTable:= TFDMemTable.Create(Nil);
with pMemTable do
begin
FieldDefs.Add('Column1', ftInteger);
FieldDefs.Add('Column2', ftInteger);
CreateDataSet;
// Assign the procedures
AfterPost:= MyAfterPost;
AfterDelete:= MyAfterDelete;
end;
// Create DataSource
Ds:= TDataSource.Create(Self);
Ds.DataSet:= pMemTable;
// Create DBNavigator
Navigator:= TDBNavigator.Create(Self);
with Navigator do
begin
Align:= alTop;
Parent:= Self;
DataSource:= Ds;
end;
// Create DBGrid
Grid:= TDBGrid.Create(Self);
with Grid do
begin
Align:= alClient;
Parent:= Self;
DataSource:= Ds;
OnTitleClick:= GridTitleClick;
end;
//
Self.Width:= 250;
Self.Height:= 250;
Self.BorderStyle:= bsDialog;
Self.Position:= poScreenCenter;
end;
procedure TForm1.GridTitleClick(Column: TColumn);
begin
{
The events now is enabled on creation, if you click on "Column1" title
then you disable them, if you click on "Column2" title, you enable them again.
}
if Column.Index = 0 then
begin
pMemTable.AfterPost:= nil;
pMemTable.AfterDelete:= nil;
end
else
begin
pMemTable.AfterPost:= MyAfterPost;
pMemTable.AfterDelete:= MyAfterDelete;
end;
end;
procedure TForm1.MyAfterDelete(ADataSet: TDataSet);
begin
// You will see this message after post
ShowMessage('After Delete Fired');
end;
procedure TForm1.MyAfterPost(ADataSet: TDataSet);
begin
// You will see this message after delete
ShowMessage('After Post Fired');
end;
end.
最后,我建议访问那些页面并阅读它们:
两个事件的类型都是TDataSetNotifyEvent
。使用两个这种类型的局部变量来临时保存事件。
要禁用事件,请将它们保存到临时变量中,然后将它们置零。
完成操作后,从临时变量中恢复实际事件。
procedure UpdateMemtable (var pMemTable : TFDmemtable);
var
tmpAfterPost,
tmpAfterDelete: TDataSetNotifyEvent
begin
tmpAfterPost := pMemTable.AfterPost;
tmpAfterDelete := pMemTable.AfterDelete;
pMemTable.AfterPost := nil;
pMemTable.AfterDelete := nil;
TRY
with pMemTable do
begin
{ code to process pMemtable }
end;
FINALLY
pMemTable.AfterPost := tmpAfterPost;
pMemTable.AfterDelete := tmpAfterDelete;
END;
end;
我有一个由多个表单共享的 DataModule,我在其中构建了一个过程来处理作为参数传递的 TFDMemtable。为了处理它,我必须禁用事件 AfterPost 和 AfterDelete,并且在结束处理时我必须重新启用它们。我没有成功启用它们,因为我无法以 "actualnameAfterpost".
的形式获取这些事件的实际名称我试过了:
pMemTable.AfterPost := @pMemTable.AfterPost ; // Result ==> compile error
pMemTable.AfterPost := addr(pMemTable.AfterPost) ; // Result ==> compile error
pMemTable.AfterPost := MethodAddress(Pmemtable.ClassName +'AfterPost'); //
Result ==> compile error
这是主要代码:
procedure UpdateMemtable (var pMemTable : TFDmemtable);
begin
pMemTable.AfterPost := nil;
pMemTable.AfterDelete := nil;
TRY
with pMemTable do
begin
{ code to process pMemtable }
end;
FINALLY
pMemTable.AfterPost := ["actualmemtablenameAfterPost" ??];
pMemTable.AfterDelete := ["actualmemtablenameAfterDelete" ??];
END;
end;
谢谢大家!
您只需要编写您的程序,然后将它们分配为
...
private
{ Private declarations }
procedure MyAfterPost(ADataSet: TDataSet);
procedure MyAfterDelete(ADataSet: TDataSet);
...
procedure TForm1.MyAfterDelete(ADataSet: TDataSet);
begin
ShowMessage('After Delete Fired');
end;
procedure TForm1.MyAfterPost(ADataSet: TDataSet);
begin
ShowMessage('After Post Fired');
end;
....
pMemTable.AfterPost:= MyAfterPost;
pMemTable.AfterDelete:= MyAfterDelete;
这里有一个简单的示例可以帮助您理解,只需 运行 看看会发生什么
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, FireDAC.Stan.Intf, FireDAC.Stan.Option,
FireDAC.Stan.Param, FireDAC.Stan.Error, FireDAC.DatS, FireDAC.Phys.Intf,
FireDAC.DApt.Intf, Data.DB, FireDAC.Comp.DataSet, FireDAC.Comp.Client,
Vcl.ExtCtrls, Vcl.DBCtrls, Vcl.Grids, Vcl.DBGrids;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
pMemTable: TFDMemTable;
Ds: TDataSource;
Grid: TDBGrid;
Navigator: TDBNavigator;
procedure MyAfterPost(ADataSet: TDataSet);
procedure MyAfterDelete(ADataSet: TDataSet);
procedure GridTitleClick(Column: TColumn);
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
// Free all
pMemTable.Free;
Ds.Free;
Navigator.Free;
Grid.Free;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
// Create the pMemTable
pMemTable:= TFDMemTable.Create(Nil);
with pMemTable do
begin
FieldDefs.Add('Column1', ftInteger);
FieldDefs.Add('Column2', ftInteger);
CreateDataSet;
// Assign the procedures
AfterPost:= MyAfterPost;
AfterDelete:= MyAfterDelete;
end;
// Create DataSource
Ds:= TDataSource.Create(Self);
Ds.DataSet:= pMemTable;
// Create DBNavigator
Navigator:= TDBNavigator.Create(Self);
with Navigator do
begin
Align:= alTop;
Parent:= Self;
DataSource:= Ds;
end;
// Create DBGrid
Grid:= TDBGrid.Create(Self);
with Grid do
begin
Align:= alClient;
Parent:= Self;
DataSource:= Ds;
OnTitleClick:= GridTitleClick;
end;
//
Self.Width:= 250;
Self.Height:= 250;
Self.BorderStyle:= bsDialog;
Self.Position:= poScreenCenter;
end;
procedure TForm1.GridTitleClick(Column: TColumn);
begin
{
The events now is enabled on creation, if you click on "Column1" title
then you disable them, if you click on "Column2" title, you enable them again.
}
if Column.Index = 0 then
begin
pMemTable.AfterPost:= nil;
pMemTable.AfterDelete:= nil;
end
else
begin
pMemTable.AfterPost:= MyAfterPost;
pMemTable.AfterDelete:= MyAfterDelete;
end;
end;
procedure TForm1.MyAfterDelete(ADataSet: TDataSet);
begin
// You will see this message after post
ShowMessage('After Delete Fired');
end;
procedure TForm1.MyAfterPost(ADataSet: TDataSet);
begin
// You will see this message after delete
ShowMessage('After Post Fired');
end;
end.
最后,我建议访问那些页面并阅读它们:
两个事件的类型都是TDataSetNotifyEvent
。使用两个这种类型的局部变量来临时保存事件。
要禁用事件,请将它们保存到临时变量中,然后将它们置零。 完成操作后,从临时变量中恢复实际事件。
procedure UpdateMemtable (var pMemTable : TFDmemtable);
var
tmpAfterPost,
tmpAfterDelete: TDataSetNotifyEvent
begin
tmpAfterPost := pMemTable.AfterPost;
tmpAfterDelete := pMemTable.AfterDelete;
pMemTable.AfterPost := nil;
pMemTable.AfterDelete := nil;
TRY
with pMemTable do
begin
{ code to process pMemtable }
end;
FINALLY
pMemTable.AfterPost := tmpAfterPost;
pMemTable.AfterDelete := tmpAfterDelete;
END;
end;