OnButtonClick und Action-Methode
-
- Lazarusforum e. V.
- Beiträge: 999
- Registriert: Do 17. Apr 2008, 01:59
- OS, Lazarus, FPC: Mint 21.1 Cinnamon / FPC 3.2.2/Lazarus 2.2.4
- CPU-Target: Intel i7-10750 64Bit
- Wohnort: Freiburg
OnButtonClick und Action-Methode
Soeben ist mir etwas aufgefallen was Zweifel erweckt, dass dies schon immer so war:
Durch Umstrukturierung meines Programms hatte ich auf einem Button ein Action eingetragen. Gleichzeitig war aber noch versehentlich die (aus einer früheren Programmversion) OnButtonClick-Funktion eingetragen.
(Sowohl die unter Action als auch die unter OnButtonClick abgelegte Methode hatten den selben Inhalt.)
Beim Klicken des Buttons wurden nun beide Events ausgeführt.
1. War dies schon immer so?
2. Ist dies beabsichtigt? Wenn ja, welcher Aufruf wird priorisiert ausgeführt?
Durch Umstrukturierung meines Programms hatte ich auf einem Button ein Action eingetragen. Gleichzeitig war aber noch versehentlich die (aus einer früheren Programmversion) OnButtonClick-Funktion eingetragen.
(Sowohl die unter Action als auch die unter OnButtonClick abgelegte Methode hatten den selben Inhalt.)
Beim Klicken des Buttons wurden nun beide Events ausgeführt.
1. War dies schon immer so?
2. Ist dies beabsichtigt? Wenn ja, welcher Aufruf wird priorisiert ausgeführt?
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.
Re: OnButtonClick und Action-Methode
Ja, zumindest habe ich das eben mal bei 1.2.0 getestet.MacWomble hat geschrieben:1. War dies schon immer so?
Ich würde das aktuelle Verhalten als richtig einschätzen, da wenn der User einen Button klickt, sollte gemäß der System Messages auch immer OnMouseDown, OnClick und OnMouseUp gefeuert werden (oder sollten diese dann bei einer TActionzuweisung auch nicht mehr gefeuert werden). Aber man könnte ja mal Delphi testen, wie es sich dort verhält.MacWomble hat geschrieben:2. Ist dies beabsichtigt? Wenn ja, welcher Aufruf wird priorisiert ausgeführt?
Zuerst wird der Event Handler von OnClick ausgeführt, dann von Action.OnExecute. Wenn du mit Actions arbeitest, dann stell doch alles auf diese um.
Code: Alles auswählen
type
TLiveSelection = (lsMoney, lsChilds, lsTime);
TLive = Array[0..1] of TLiveSelection;
Re: OnButtonClick und Action-Methode
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:
Ich finde, die Routine müsste nach "FOnClick" verlassen werden, also so:
Damit zeigt mein Beispiel-Programm dasselbe Verhalten wie bei Delphi. Ich weiß natürlich nicht, ob diese Änderung irgendwelche Seiteneffekte bei anderen Controls hat...
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...
- Dateianhänge
-
- action_button.zip
- (4.38 KiB) 77-mal heruntergeladen
Re: OnButtonClick und Action-Methode
Ich denke OnClickIsActionExecute sollte genau das verhindern, daß der Event Handler doppelt aufgerufen wird, wenn es sich um die selbe Methode handelt, ansonsten werden beide aufgerufen.
[Edit]:
Wenn Delphi ein anderes Verhalten an den Tag legt, können wir die Methode stark vereinfachen:Keine Ahnung, ob das Verhalten jetzt besser ist?
[Edit]:
Wenn Delphi ein anderes Verhalten an den Tag legt, können wir die Methode stark vereinfachen:
Code: Alles auswählen
procedure TControl.Click;
begin
//DebugLn(['TControl.Click ',DbgSName(Self)]);
if csDesigning in ComponentState then Exit;
if Assigned(FOnClick) then
FOnClick(Self)
else
if Assigned(ActionLink) then
ActionLink.Execute(Self);
end;
Code: Alles auswählen
type
TLiveSelection = (lsMoney, lsChilds, lsTime);
TLive = Array[0..1] of TLiveSelection;
Re: OnButtonClick und Action-Methode
Früher wurde der OnExcute-Handler der Action im OnClick-Handler des Controls eingetragen, so wie bei Delphi übrigens auch. OnClickIsActionExecute prüft daher, ob die beiden Handler identisch sind. Jetzt bleibt OnClick bei Verwendung einer Action leer, und der jetzige Code erscheint mir etwas überholt zu sein. Ich denke schon, dass dein Code funktionieren sollte, Ich meine sogar, dass er auch vorher schon funktioniert hätte. Auf der anderen Seite, warum schreibt jemand so umständlichen Code wie den heutigen ohne Not, wenn nicht doch etwas dahinter steckt, an das wir nicht denken?
Ich habe übrigens eben die Änderung mit dem "exit" hochgeladen, so dass ab jetzt im Trunk nur noch 1 Event aufgerufen werden sollte.
Ich habe übrigens eben die Änderung mit dem "exit" hochgeladen, so dass ab jetzt im Trunk nur noch 1 Event aufgerufen werden sollte.
-
- Lazarusforum e. V.
- Beiträge: 999
- Registriert: Do 17. Apr 2008, 01:59
- OS, Lazarus, FPC: Mint 21.1 Cinnamon / FPC 3.2.2/Lazarus 2.2.4
- CPU-Target: Intel i7-10750 64Bit
- Wohnort: Freiburg
Re: OnButtonClick und Action-Methode
Mit dem Exit funktionieren die Buttons des RXSidepanel nicht mehr in jedem Fall!
Das ist also nicht die Lösung !
Das ist also nicht die Lösung !
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.
Re: OnButtonClick und Action-Methode
Nur weiß ich nicht, was das RXSIdepanel ist.
-
- Lazarusforum e. V.
- Beiträge: 999
- Registriert: Do 17. Apr 2008, 01:59
- OS, Lazarus, FPC: Mint 21.1 Cinnamon / FPC 3.2.2/Lazarus 2.2.4
- CPU-Target: Intel i7-10750 64Bit
- Wohnort: Freiburg
Re: OnButtonClick und Action-Methode
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.
Re: OnButtonClick und Action-Methode
Ich hab's mir installiert. Find ich nicht. In welcher Datei ist das enthalten?
-
- Lazarusforum e. V.
- Beiträge: 999
- Registriert: Do 17. Apr 2008, 01:59
- OS, Lazarus, FPC: Mint 21.1 Cinnamon / FPC 3.2.2/Lazarus 2.2.4
- CPU-Target: Intel i7-10750 64Bit
- Wohnort: Freiburg
Re: OnButtonClick und Action-Methode
Sorry, TRXViewsPanel - hatte den Namen statt die Klasse abgelesen
Der OnClick auf Items wird nicht mehr immer erkannt, wenn das exit verwendet wird.
Der OnClick auf Items wird nicht mehr immer erkannt, wenn das exit verwendet wird.
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.
Re: OnButtonClick und Action-Methode
Nach einigem Hin-und-her habe ich das "exit" wieder rückgängig gemacht. Die Komponente könnte man zwar einfach fixen, aber möglicherweise haben andere auch noch dieses Problem. Und so groß ist der Vorteil von dem Fix nun auch wieder nicht.