Mein Verständnis ist, dass es sich mit dem auszuführenden Event-Handler genauso verhalten sollte wie mit den anderen Properties, die von Actions verändert werden: Wenn ich z.B. einen Button mit einer Action verbinde, wird seine Caption durch die Caption der Action ersetzt; wenn ich hinterher die Caption des Buttons verändere, gilt diese. Der Button hat Priorität gegenüber der Action.
Genauso ist es mit dem Eventhandler bei Delphi (siehe beigefügtes Programm): Bei einem Klick auf einen Button, dem eine Action zugewiesen ist, der aber eine eigene OnClick-Routine hat, wird die OnClick-Routine ausgeführt - auf keinen Fall werden beide ausgeführt, so wie es bei Lazarus der Fall ist.
Ich denke, hier liegt ein Fehler vor, der gemeldet werden sollte. Ich erinnere mich, dass mit den Eventhandlern bei Actions vor einiger Zeit etwas geändert worden ist - hoffentlich ist da nichts ver-schlimm-bessert worden. Andererseits hat Michl recht, dass beide Events auch schon mit Laz 1.2 aufgerufen werden.
Das beigefügte Programm kann sowohl mit Delphi als auch mit Lazarus verwendet werden.
[EDIT]
Ich habe mir jetzt die in TControl eingeführte Click-Methode angesehen:
Code: Alles auswählen
procedure TControl.Click;
function OnClickIsActionExecute: boolean;
begin
Result:=false;
if Action=nil then exit;
if not Assigned(Action.OnExecute) then exit;
if not Assigned(FOnClick) then exit;
Result:=CompareMethods(TMethod(FOnClick),TMethod(Action.OnExecute));
end;
var
CallAction: Boolean;
begin
//DebugLn(['TControl.Click ',DbgSName(Self)]);
CallAction:=(not (csDesigning in ComponentState)) and (ActionLink <> nil);
// first call our own OnClick if it differs from Action.OnExecute
if Assigned(FOnClick)
and ((not CallAction) or (not OnClickIsActionExecute)) then
FOnClick(Self);
// then trigger the Action
if CallAction then
ActionLink.Execute(Self);
end;
Ich finde, die Routine müsste nach "FOnClick" verlassen werden, also so:
Code: Alles auswählen
procedure TControl.Click;
function OnClickIsActionExecute: boolean;
begin
Result:=false;
if Action=nil then exit;
if not Assigned(Action.OnExecute) then exit;
if not Assigned(FOnClick) then exit;
Result:=CompareMethods(TMethod(FOnClick),TMethod(Action.OnExecute));
end;
var
CallAction: Boolean;
begin
//DebugLn(['TControl.Click ',DbgSName(Self)]);
CallAction:=(not (csDesigning in ComponentState)) and (ActionLink <> nil);
// first call our own OnClick if it differs from Action.OnExecute
if Assigned(FOnClick)
and ((not CallAction) or (not OnClickIsActionExecute)) then begin
FOnClick(Self);
exit; // <--- NEU
end;
// then trigger the Action
if CallAction then
ActionLink.Execute(Self);
end;
Damit zeigt mein Beispiel-Programm dasselbe Verhalten wie bei Delphi. Ich weiß natürlich nicht, ob diese Änderung irgendwelche Seiteneffekte bei anderen Controls hat...