OnButtonClick und Action-Methode

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.

OnButtonClick und Action-Methode

Beitragvon MacWomble » 13. Jun 2018, 18:11 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? :shock:
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.
MacWomble
 
Beiträge: 607
Registriert: 17. Apr 2008, 00:59
Wohnort: Freiburg
OS, Lazarus, FPC: Mint 19 Cinnamon / CodeTyphon Generation V Plan 6.60 | 
CPU-Target: Intel i7 64/32 Bit
Nach oben

Beitragvon Michl » 14. Jun 2018, 09:18 Re: OnButtonClick und Action-Methode

MacWomble hat geschrieben:1. War dies schon immer so?
Ja, zumindest habe ich das eben mal bei 1.2.0 getestet.

MacWomble hat geschrieben:2. Ist dies beabsichtigt? Wenn ja, welcher Aufruf wird priorisiert ausgeführt?
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.

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; 
Michl
 
Beiträge: 2260
Registriert: 19. Jun 2012, 11:54
OS, Lazarus, FPC: Win7 Laz 1.7 Trunk FPC 3.1.1 Trunk | 
CPU-Target: 32Bit/64bit
Nach oben

Beitragvon wp_xyz » 14. Jun 2018, 10:18 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:
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...
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
wp_xyz
 
Beiträge: 2672
Registriert: 8. Apr 2011, 08:01

Beitragvon Michl » 14. Jun 2018, 11:24 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:
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;
Keine Ahnung, ob das Verhalten jetzt besser ist?
Code: Alles auswählen
type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 
Michl
 
Beiträge: 2260
Registriert: 19. Jun 2012, 11:54
OS, Lazarus, FPC: Win7 Laz 1.7 Trunk FPC 3.1.1 Trunk | 
CPU-Target: 32Bit/64bit
Nach oben

Beitragvon wp_xyz » 14. Jun 2018, 12:14 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.
wp_xyz
 
Beiträge: 2672
Registriert: 8. Apr 2011, 08:01

Beitragvon MacWomble » 15. Jun 2018, 19:28 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 !
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.
MacWomble
 
Beiträge: 607
Registriert: 17. Apr 2008, 00:59
Wohnort: Freiburg
OS, Lazarus, FPC: Mint 19 Cinnamon / CodeTyphon Generation V Plan 6.60 | 
CPU-Target: Intel i7 64/32 Bit
Nach oben

Beitragvon wp_xyz » 15. Jun 2018, 19:50 Re: OnButtonClick und Action-Methode

Nur weiß ich nicht, was das RXSIdepanel ist.
wp_xyz
 
Beiträge: 2672
Registriert: 8. Apr 2011, 08:01

Beitragvon MacWomble » 15. Jun 2018, 19:54 Re: OnButtonClick und Action-Methode

Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.
MacWomble
 
Beiträge: 607
Registriert: 17. Apr 2008, 00:59
Wohnort: Freiburg
OS, Lazarus, FPC: Mint 19 Cinnamon / CodeTyphon Generation V Plan 6.60 | 
CPU-Target: Intel i7 64/32 Bit
Nach oben

Beitragvon wp_xyz » 15. Jun 2018, 22:49 Re: OnButtonClick und Action-Methode

Ich hab's mir installiert. Find ich nicht. In welcher Datei ist das enthalten?
wp_xyz
 
Beiträge: 2672
Registriert: 8. Apr 2011, 08:01

Beitragvon MacWomble » 16. Jun 2018, 07:20 Re: OnButtonClick und Action-Methode

Sorry, TRXViewsPanel - hatte den Namen statt die Klasse abgelesen :oops:

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.
MacWomble
 
Beiträge: 607
Registriert: 17. Apr 2008, 00:59
Wohnort: Freiburg
OS, Lazarus, FPC: Mint 19 Cinnamon / CodeTyphon Generation V Plan 6.60 | 
CPU-Target: Intel i7 64/32 Bit
Nach oben

Beitragvon wp_xyz » 16. Jun 2018, 13:52 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.
wp_xyz
 
Beiträge: 2672
Registriert: 8. Apr 2011, 08:01

• Themenende •

Zurück zu Sonstiges



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 7 Gäste

porpoises-institution
accuracy-worried