Как назначить события TFDMemtable AfterPost и AfterDelete во время выполнения? - PullRequest
0 голосов
/ 23 марта 2019

У меня есть 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;

Спасибо всем!

Ответы [ 2 ]

4 голосов
/ 23 марта 2019

Оба события имеют тип 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;
2 голосов
/ 23 марта 2019

Вам нужно просто написать свои процедуры, а затем назначить их как

...
  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.

Наконец, я предлагаю посетить эти страницы и прочитать их:

...