Reputation: 555
I'm deriving from TClientdataset and trying to define an 'always run' AfterPost event. I have tried assign my AfterPost event at the constructor, but the derived component does not seem to pick it up
TMyClientDataset = class(TClientDataset)
private
FInserting: Boolean; //set to True at the MyOnNewRecord event
property FuserAfterPost: TDataSetNotifyEvent;
...
public
constructor Create(AOwner: TComponent);
...
implementation
constructor TMyClientDataset.Create(AOwner: TComponent)
begin
...
if Assigned(AfterPost) then
FuserAfterPost := AfterPost;
Afterpost := MyAfterPost;
...
end;
procedure TMyClientDataset.MyAfterPost(Dataset: TDataset);
begin
If Assigned(FuserAfterPost) then
FuserAfterPost(Dataset);
FInserting := False;
end;
What I'm trying to do: On new record, set Finserting := True
; On after post, run the user supplied OnAfterPost and set FInserting := False
; But the MyAfterpost event won't even run. I'm assuming the constructor is not the right place to do AfterPost := MyAfterPost;
? Where should it go?
Upvotes: 3
Views: 255
Reputation: 14832
Sertac's answer is excellent guidance on this type of problem. And yes it does answer the question you asked, but it's missing something.
It seems to me that you have an XY problem, and failed to ask the correct question. There is no need for you to try to manually track FInserting
. Delphi already does this. Take a look at TDataSet.State and TDataSetState.
Basically your FInserting
is equivalent to State = dsInsert
.
Although, as you have pointed out, your FInserting
flag is True
in OnAfterPost
(which makes it misleading, and on that basis is technically a bug).
Upvotes: 0
Reputation: 54812
There's no good place for what you want to do. Because a user of the component may attach a handler or nil to the event handler anytime while the program is running, not just at design time. May detach an existing handler too. Then your code will not run.
For this reason, VCL employs a two step call to event handlers. First is a virtual procedure which, generally, does nothing more than to call a possible event handler. In your case, this is DoAfterPost.
TMyClientDataset = class(TClientDataset)
..
protected
procedure DoAfterPost; override;
...
procedure TMyClientDataset.DoAfterPost;
begin
inherited;
FInserting := False;
end;
For a case when no such opportunity exists, there would be no chance but properly document and hope for the user of the component reads and complies with it. Overriding Loaded would be the right place to backup an existing design-time attached handler.
Upvotes: 3