views:

302

answers:

3

In Delphi 2009 I have a Form with a procedure MyProcedure that writes to a label on the Form. The form uses a DataModule with a ClientDataSet. When the AfterScroll event of the ClientDataSet is fired MyProcedure should be executed. To avoid circular references and more important, as I want the DataModule to be reusable, the DataModule should not reference to this specific Form.

In short, I hope that I can access the AfterScroll event from my Form. Can I hook up the Afterscroll event on the DataModule from my Form? I thought it should be possible, but I cannot remember how to do it. Thanks in advance.

+2  A: 

Should be something like:

procedure TForm1.FormCreate(Sender: TObject);
begin
  DataModule1.MyCDS.AfterScroll := MyAfterScrollHandler;
end;
Ulrich Gerhardt
Thank you Ulrich. I accepted Mihaela's answer because of the longer explanation, but if it were possible I would have accepted yours as well.
RR-NL
+5  A: 

You put an event property in your DataModule:

private
FOnAfterScroll : TNotifyEvent;
public
property OnAfterScroll   : TNotifyEvent read FOnAfterScroll write FOnAfterScroll;

You then call that event in the AfterScroll procedure in the DataModule:

If Assigned(FOnAfterScroll) then FOnAfterScroll(Self);

In Form: declare event handler

procedure HandleAfterScroll(Sender : TObject);

Then you assign a procedure to DataModule's OnAfterScroll

Datamodule1.OnAfterScroll := MyHandleAfterScroll;

Another way would be to send a custom windows message from DataModule and to respond to that message in the Form.

Mihaela
Thank you Mihaela, works like a charm. To be precise, do change FAfterScroll to FOnAfterScroll in the 'If Assigned (FAfterScroll)' statement :)
RR-NL
+1  A: 

If all you want is to declare the event handler in a different unit, like the form, go with Ulrich's suggestion. If you want to be able to put a default event handler in your data module but then be able to extend its behavior, it takes a bit more work. You can do this by adding an event to the data module.

Define a method pointer with the appropriate signature and add one to the data module at public scope, like so:

type
  TMyEvent = procedure({arg list here}) of object;

  TMyDataModule = class(TDataModule)
  //definition goes here
    procedure MyTableAfterScroll({arg list here});
  private
    FExternalEvent: TMyEvent;
  public
    property ExternalEvent: TMyEvent read FMyEvent write FMyEvent
  end;

implementation

procedure TMyDataModule.MyTableAfterScroll({arg list here});
begin
  //do whatever
  if assigned(FExternalEvent) then
    FExternalEvent({whatever arguments});
  //do more stuff, if you'd like
end;

To hook it up, in your form's OnCreate, just assign your procedure to MyDataModule.ExternalEvent and you'll be good to go.

Mason Wheeler