Jump to content
Ian Branch

Assign an event at run time??

Recommended Posts

Hi Team,

I have this procedure..

procedure TdmC.dsJobTicketsDataChange(Sender: TObject; Field: TField);
begin
...
....

Currently it is 'hard coded' to the Datasource.

I want to assign it at run time if possible.

What steps do I need to take to do that please??

 

The datamodule, TdmC, is used by two applications with conditionals isolating relevant code.

By way of example, ATT I have conditionals inside this procedure  that basically remove any code.

I feel it would be neater to actually have the procedure assigned to the event IF the relevant conditional is true.

There are several other procedures in the unit that are treated the same.

 

Of course I am open to alternatives.. 🙂

 

Regards & TIA,

Ian

Edited by Ian Branch

Share this post


Link to post
Quote

 

type
  TYourTypeName = {reference to } procedure(Sender: TObject; Field: TField) { of object} ;

... your classs
Private
  FYourEvent :TYourTypeName;
...
Public
   property YourEvent:TYourTypeName read FYourEvent write FYourEvent;
...

// "reference to" if using regular procedure
procedure HelloWorld(Sender: TObject; Field: TField);
...

// else, using a procedure "of object"
TForm1.... class
...
Private
   procedure HelloWorld(Sender: TObject; Field: TField);
...

// Assigning
  // into class
  FYourEvent := HelloWord-proc;
  // in your code
   YourEvent := HelloWord;
...

// executing
if Assigned( FYourEvent ) then
   FYourEvent( obj, fld );

// It would be this?

// as you are using in 2 apps, you can use "Compiler Directives", or any other way ...

{$DEFINE APP1}
...
{$IFDEF APP1}
...
{$ELSE}

...

{$ENDIF}

 

Edited by programmerdelphi2k

Share this post


Link to post

Similar topic last week, short so its worth a review

Declare your own procedures to handle the event, here there is one for NewTicket and OldTicket:  See the notes in the Datamodule create procedure for if you want to handle it via compiler defines or switch based on some app value using an if statement. 

interface

uses
  System.SysUtils, System.Classes, Data.DB, Datasnap.DBClient, FireDAC.Stan.Intf, FireDAC.Stan.Option,
  FireDAC.Stan.Param, FireDAC.Stan.Error, FireDAC.DatS, FireDAC.Phys.Intf, FireDAC.DApt.Intf, FireDAC.Comp.DataSet,
  FireDAC.Comp.Client;

type
  TdmMarshalDemo = class(TDataModule)
    cdsFeatures: TClientDataSet;
    cdsFeaturesFeatureName: TStringField;
    fdMemTblVideos: TFDMemTable;
    fdMemTblVideosVideoID: TStringField;
    fdMemTblVideosTitle: TStringField;
    fdMemTblVideosDescription: TStringField;
    dsVideos: TDataSource;
    procedure DataModuleCreate(Sender: TObject);
  private
    procedure dsNewTicketDataChange(Sender: TObject; Field: TField); 
    procedure dsOldTicketDataChange(Sender: TObject; Field: TField); 
  public
    function CurrentVideo: TDemoVideo;
  end;

var
  dmMarshalDemo: TdmMarshalDemo;

implementation

{%CLASSGROUP 'FMX.Controls.TControl'}
{$R *.dfm}
{ TdmMarshalDemo }

procedure TdmMarshalDemo.DataModuleCreate(Sender: TObject);
begin

  //compiler defines
{$IFDEF RELEASE}
  dsVideos.OnDataChange := dsNewTicketDataChange;
{$ELSE}
  dsVideos.OnDataChange := dsOldTicketDataChange;
{$ENDIF}

//app logic
  if 1 = 1 then
    dsVideos.OnDataChange := dsNewTicketDataChange
  else
    dsVideos.OnDataChange := dsOldTicketDataChange;
end;

procedure TdmMarshalDemo.dsNewTicketDataChange(Sender: TObject; Field: TField);
begin

end;

procedure TdmMarshalDemo.dsOldTicketDataChange(Sender: TObject; Field: TField);
begin

end;

end.

 

Share this post


Link to post
10 hours ago, Ian Branch said:

I want to assign it at run time if possible.

What steps do I need to take to do that please??

Move the event to the private section, so the Form Designer won't fiddle with it.

At the appropriate code determine which of the eligible methods must be used and assign it to the TDataSource OnDataChange event.

// assuming this code runs inside the datamodule. Otherwise myDataSource must be qualified
begin
  if SomeCondition then 
    myDataSource.OnDataChange := MyEventHandler
  else
    myDataSource.OnDataCHange := MyOtherEventHandler;
...    

Personally I would rather extract the code from inside the event to a separate method or different separate methods. Then you can make the decision inside the hard-wired event:

procedure TdmC.dsJobTicketsDataChange(Sender: TObject; Field: TField);
begin
  if SomeCondition then
    MyEvent(Sender, Field)
  else
    MyOtherEvent(Sender, Field);
end;

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×