The idea is that when no event handler is assigned, the component/class/object works correctly. That's why they are procedure and returned values are passed as var argument, just like I have done in my example:
function TSearchFrom.GetSearchTextLine(ADataIdx : Integer) : String;
begin
Result := ''; // This will be the search line if no event handler assigned
if Assigned(FOnGetSearchTextLine) then
FOnGetSearchTextLine(Self, ADataIdx, Result);
end;
Another design tips is that if an event is triggered several times, a procedure is created for that:
procedure TSearchForm.TriggerGetSearchTextLine(ADataIdex : Integer; var SearchText : String);
begin
if Assigned(FOnGetSearchTextLine) then
FOnGetSearchTextLine(Self, ADataIdx, Result);
end;
and then you'll write:
function TSearchFrom.GetSearchTextLine(ADataIdx : Integer) : String;
begin
Result := ''; // This will be the search line if no event handler assigned
TriggerGetSearchTextLine(ADataIdx, Result);
end;