dormky 3 Posted January 20 In Data.DB, the dataset events are defined as TDataSetNotifyEvent = procedure(DataSet: TDataSet) of object; This means that such code as MyTableTest.BeforeDelete := procedure (d: TDataSet) begin LogTableOperation('MyTableTestBeforeDelete'); end; not valid. Is there anyway of casting this ? I'd rather not define a procedure in my data module for every event of every table... Share this post Link to post
David Heffernan 2380 Posted January 20 24 minutes ago, dormky said: Is there anyway of casting this ? No, they are fundamentally different things in terms of implementation. Share this post Link to post
Remy Lebeau 1504 Posted January 21 This is documented behavior: https://docwiki.embarcadero.com/RADStudio/en/Anonymous_Methods_in_Delphi Quote you cannot assign an anonymous method to a regular method pointer. Method references are managed types, but method pointers are unmanaged types. Thus, for type-safety reasons, assigning method references to method pointers is not supported. For instance, events are method pointer-valued properties, so you cannot use an anonymous method for an event. 1 Share this post Link to post
JonRobertson 76 Posted January 21 On 1/20/2025 at 8:19 AM, dormky said: I'd rather not define a procedure in my data module for every event of every table... If several tables will use events with identical functionality, such as logging, you can have a single event assigned to multiple tables: procedure TForm1.AllTablesBeforeDelete(DataSet: TDataSet); begin LogTableOperation(DataSet.Name + 'BeforeDelete'); end; MyTable1Test.BeforeDelete := AllTablesBeforeDelete; MyTable2Test.BeforeDelete := AllTablesBeforeDelete; MyTable3Test.BeforeDelete := AllTablesBeforeDelete; Or assign the event handler to each table using the object inspector. Share this post Link to post
dormky 3 Posted January 22 18 hours ago, JonRobertson said: If several tables will use events with identical functionality, such as logging, you can have a single event assigned to multiple tables: procedure TForm1.AllTablesBeforeDelete(DataSet: TDataSet); begin LogTableOperation(DataSet.Name + 'BeforeDelete'); end; MyTable1Test.BeforeDelete := AllTablesBeforeDelete; MyTable2Test.BeforeDelete := AllTablesBeforeDelete; MyTable3Test.BeforeDelete := AllTablesBeforeDelete; Or assign the event handler to each table using the object inspector. That's what I ended up with yes Share this post Link to post
Softacom | Company 7 Posted February 13 You can't just convert it, but you can make same behaviour type TDataSetAnonimouseEvent = reference to procedure(DataSet: TDataSet); TForm3 = class(TForm) FDQuery1: TFDQuery; bntAddNewEvent: TButton; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure bntAddNewEventClick(Sender: TObject); private { Private declarations } FEventLinks : TDictionary<TComponent, TDataSetAnonimouseEvent>; public { Public declarations } procedure AllTablesBeforeDelete(DataSet: TDataSet); end; var Form3: TForm3; implementation {$R *.dfm} procedure TForm3.AllTablesBeforeDelete(DataSet: TDataSet); begin //check if we have anonymous event for this component if FEventLinks.ContainsKey(DataSet) then begin //call anonymous event FEventLinks[DataSet](DataSet); end; end; procedure TForm3.bntAddNewEventClick(Sender: TObject); begin //link anonymous event to specific component FEventLinks.Add(FDQuery1, procedure(DataSet: TDataSet) begin ShowMessage('Anonimouse event!'); end ); end; procedure TForm3.FormCreate(Sender: TObject); begin FEventLinks := TDictionary<TComponent, TDataSetAnonimouseEvent>.Create; FDQuery1.BeforeDelete := AllTablesBeforeDelete; end; procedure TForm3.FormDestroy(Sender: TObject); begin FreeAndNil(FEventLinks); end; Share this post Link to post
HolgerX 7 Posted February 14 Hmm.. or you make it with a simple helper: type TMakeObjectFunc = class public class procedure Log(d: TDataSet); end; { TMakeObjectFunc } class procedure TMakeObjectFunc.Log(d: TDataSet); begin LogTableOperation('MyTableTestBeforeDel?ete'); end; procedure TForm1.FormCreate(Sender: TObject); begin MyTableTest.BeforeDelete := TMakeObjectFunc.Log; end; Share this post Link to post
yonojoy 2 Posted February 18 Or you could use a wrapper (as demonstrated for TNotifyEvent in https://stackoverflow.com/questions/11491593/tproctobject-to-tnotifyevent): MyTableTest.BeforeDelete := AnonProcToDataSetNotifyEvent(MyTableTest, procedure (D: TDataSet) begin LogTableOperation('MyTableTestBeforeDelete'); end); Share this post Link to post