AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi on[XYZ]-Methoden: Nicht aufrufen wenn Programmcode die Komponente ändert
Thema durchsuchen
Ansicht
Themen-Optionen

on[XYZ]-Methoden: Nicht aufrufen wenn Programmcode die Komponente ändert

Ein Thema von Der schöne Günther · begonnen am 22. Jul 2013 · letzter Beitrag vom 24. Jul 2013
Antwort Antwort
Seite 1 von 2  1 2      
Der schöne Günther

Registriert seit: 6. Mär 2013
6.196 Beiträge
 
Delphi 10 Seattle Enterprise
 
#1

on[XYZ]-Methoden: Nicht aufrufen wenn Programmcode die Komponente ändert

  Alt 22. Jul 2013, 11:03
Der Titel ist eine Katastrophe, bessere Vorschläge erbeten

Konkretes Beispiel: Setze ich in meiner VCL-TRadioGroup die Property ItemIndex um, so ergibt sich folgende Aufrufreihenfolge:

Code:
TCustomRadioGroup.SetItemIndex() -> TControl.Click -> myRadioGroup.OnClick()
Ich möchte nicht, dass das ganze Geraffel hintendran (onClick-Ereignishandler) ausgeführt wird, das ist doch nur dafür, wenn der Benutzer aktiv draufklickt und etwas ändern möchte.

Wie gehe ich hier am besten vor? Ist meine Absicht falsch? Setze ich das onClick -Ereignis vorher auf nil , ändere dann den ItemIndex und setze onClick wieder zurück?

Ich habe schon gesehen, wie Leute die Tag-Property dafür benutzt haben, um zwischen "eigener" Änderung und Veranlassung durch den Benutzer zu unterscheiden, aber das erscheint mir irgendwie nicht richtig...
  Mit Zitat antworten Zitat
Benutzerbild von Codehunter
Codehunter

Registriert seit: 3. Jun 2003
Ort: Thüringen
2.283 Beiträge
 
Delphi 12 Athens
 
#2

AW: on[XYZ]-Methoden: Nicht aufrufen wenn Programmcode die Komponente ändert

  Alt 22. Jul 2013, 12:07
Ich mache das meistens so, dass im jeweiligen Formular eine globale boolsche Variable existiert. Die wird abgefragt wenn ein OnClick oder sonstwas ausgeführt wird. Bei Operationen, die keine Eventhandler auslösen sollen, wird die Variable vorher gesetzt und am Ende der Operation wieder zurückgesetzt.
Ich mache grundsätzlich keine Screenshots. Schießen auf Bildschirme gibt nämlich hässliche Pixelfehler und schadet der Gesundheit vom Kollegen gegenüber. I und E zu vertauschen hätte den selben negativen Effekt, würde aber eher dem Betriebsklima schaden
  Mit Zitat antworten Zitat
silver-moon-2000

Registriert seit: 18. Feb 2007
Ort: Schweinfurt
170 Beiträge
 
Delphi XE Professional
 
#3

AW: on[XYZ]-Methoden: Nicht aufrufen wenn Programmcode die Komponente ändert

  Alt 22. Jul 2013, 21:38
Um auch mal meinen Mist dazu zu geben, obwohl schon alles gesagt ist

Ich mache das meistens so, dass im jeweiligen Formular eine globale boolsche Variable existiert. Die wird abgefragt wenn ein OnClick oder sonstwas ausgeführt wird. Bei Operationen, die keine Eventhandler auslösen sollen, wird die Variable vorher gesetzt und am Ende der Operation wieder zurückgesetzt.
Genauso mache ich das eigentlich auch:

"in der Logik"
Delphi-Quellcode:
//Feststellen, dass etwas in der GUI geändert werden muss
GUI.DoNotTriggerEvents := True;
//Änderungen in der GUI vornehmen
GUI.DoNotTriggerEvents := False;
"in der GUI"

Delphi-Quellcode:
private
  FDoNotTriggerEvents : Boolean;
public
  property DoNotTriggerEvents ...

[...]

if Assigned(OnRadioGroupClick) and (not FDoNotTriggerEvents) then
  OnRadioGroupClick(...);
Tobias
Bitte nicht hauen , ich weiß es nicht besser
  Mit Zitat antworten Zitat
Furtbichler
(Gast)

n/a Beiträge
 
#4

AW: on[XYZ]-Methoden: Nicht aufrufen wenn Programmcode die Komponente ändert

  Alt 23. Jul 2013, 08:13
Ich persönlich glaube, das diese Problematik nur dann* auftritt, wenn man das VM-Muster (Viewmodel) nicht umsetzt.

Wegen der -bei korrektem Design- 1:1 Zuordnung von VM-Property und GUI-Control sollte bzw. muß dann imho jede Änderung des Controlzustandes (z.B. Setzen vom ItemIndex) die entsprechende Kaskade von OnXXXX-Ereignisaufrufen nach sich ziehen.

...Die netten Endlosschleifchen, ...
sollten bei der stringenten Umsetzung des Patterns nicht auftreten:
Delphi-Quellcode:
Procedure TMyViewModel.SetMyProperty (Const Value : TSomeType)
begin
  if Value = MyProperty Then exit;
  fMyProperty := Value;
  RaiseOnChaingeMyPropertyEvent;
end;
Einzige Ausnahme: Eine Double-Property verweigert gerne einmal den Endlosschleifenshowstopper If Value = MyValue then Exit wegen den bekannten Double-Gleichheits-Problematiken.

Wie gesagt: Man kann sämtliche Fallstricke und Performancebremsen durch saubere Programmierung des Viewmodels eliminieren, meiner Meinung nach.


Delphi-Quellcode:
if Assigned(OnRadioGroupClick) and (not FDoNotTriggerEvents) then
  OnRadioGroupClick(...);
Tipp: Auf doppelte Verneinungen verzichten. In Bayern wird das anders verstanden. "Der soll jetzad kei' Trigger net feuan.'.

Besser:
Delphi-Quellcode:
if Assigned(OnRadioGroupClick) and FTriggerEvents then // Logik umkehren
  OnRadioGroupClick(...);
// Oder
if FDoNotTriggerEvents then exit; // Lesbarkeit erhöhen
if Assigned(OnRadioGroupClick) then
  OnRadioGroupClick(...);
Man sollte i.A. auf Flags à la 'NotXXX' verzichten, weil das Hirn beim Lesen mit solchen Verneinungen meist nicht so gut klar kommt. Hier ist das allerdings ok, denn das Flag definiert die Ausnahme von der Regel. Vielleicht wäre jedoch 'SurpressTrigger' ein besserer Name (gleiche Bedeutung, keine Verneinung).
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.933 Beiträge
 
Delphi 12 Athens
 
#5

AW: on[XYZ]-Methoden: Nicht aufrufen wenn Programmcode die Komponente ändert

  Alt 23. Jul 2013, 12:58
Einzige Ausnahme: Eine Double-Property verweigert gerne einmal den Endlosschleifenshowstopper If Value = MyValue then Exit wegen den bekannten Double-Gleichheits-Problematiken.
Einen Double vergleicht man ja auch mit SameValue.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Furtbichler
(Gast)

n/a Beiträge
 
#6

AW: on[XYZ]-Methoden: Nicht aufrufen wenn Programmcode die Komponente ändert

  Alt 24. Jul 2013, 07:12
Einen Double vergleicht man ja auch mit SameValue.
Mir schon klar, aber mein Pattern lautete If Value=fMyProperty then... und nicht If SameValue(fMyProperty,Value) then... , deshalb also der explizite Hinweis. Ich hätte den Hinweis auch auf Objekte erweitern können, aber das habe ich mir geschenkt. Da bei Double-Werten jedoch hin und wieder noch die Frage aufkommt, wieso '=' nicht funktioniert, habe ich das dann kurz und knapp angerissen. Bei Erwähnung von 'SameValue' hätte ich ausholen müssen, bei Weglassen meines knappen Zusatzes wäre ein ganz Schlauer auf die Idee gekommen, mich auf die Double-Problematik hinzuweisen, also habe ich wirklich gedacht, der kurze Hinweis reicht. Tut er wohl nicht.

...Die netten Endlosschleifchen, ...
sollten bei der stringenten Umsetzung des Patterns nicht auftreten:
Volle Zustimmung. Aber jetzt bringe das mal den VCL-Entwicklern bei, und wir haben was gewonnen
Meinst Du mit 'VCL-Entwicklern' die Entwickler der VCL? Ich bin der festen Überzeugung, das man auch verbuggte VCL-Eventkaskaden etc. über ein gut implementiertes VM-Pattern lösen kann.

Oder meinst Du mit 'VCL-Entwicklern' Entwickler, die mit der VCL entwickeln? Wenn Sie unter deiner Leitung arbeiten, dann chleudere die Purchen su Poden. Arbeiten sie nicht mit/für Dich, dann... Pech gehabt und weiter den linken Schuh ausziehen (aka den Messias spielen).

Leider gibt es hier in der DP kein Dojo, wo man sich mit solchen Implementierungen auseinandersetzen und robuste Pattern entwickeln kann.
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.688 Beiträge
 
Delphi 2007 Enterprise
 
#7

AW: on[XYZ]-Methoden: Nicht aufrufen wenn Programmcode die Komponente ändert

  Alt 23. Jul 2013, 22:54
...Die netten Endlosschleifchen, ...
sollten bei der stringenten Umsetzung des Patterns nicht auftreten:
Volle Zustimmung. Aber jetzt bringe das mal den VCL-Entwicklern bei, und wir haben was gewonnen
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.656 Beiträge
 
Delphi 12 Athens
 
#8

AW: on[XYZ]-Methoden: Nicht aufrufen wenn Programmcode die Komponente ändert

  Alt 22. Jul 2013, 12:11
Setze ich das onClick -Ereignis vorher auf nil , ändere dann den ItemIndex und setze onClick wieder zurück?
Das wäre IMO die einfachste Möglichkeit.

[edit] Oder evtl. ein BM_SETCHECK absetzen. Ähnliche Problematik, allerdings mit einer Checkbox: http://forum.delphi-treff.de/index.p...threadID=30618 [/edit]
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen

Geändert von DeddyH (22. Jul 2013 um 12:15 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.933 Beiträge
 
Delphi 12 Athens
 
#9

AW: on[XYZ]-Methoden: Nicht aufrufen wenn Programmcode die Komponente ändert

  Alt 22. Jul 2013, 12:13
Ich versuche alles so zu designen, dass der Fall gar nicht eintritt, d.h. so, dass die Eventhandler auch nur das machen, was eine Folge der Auswahl ist. Und diese direkte Folge benötige ich dann auch, wenn ich den Wert per Quelltext selbst setze.

Ansonsten benutze ich auch private Felder um das zu steuern, da man anders als bei Verwendung von Tag dafür auch am Variablennamen sieht was der tut. Wer Tag dafür benutzt gehört geteert und gefedert.

Das OnClick temporär zu entfernen halte ich auch nicht für sauber, da man dann in dem OnClick gar nichts davon merkt, dass es nicht immer greift und sich später vielleicht mal tot debuggt... das sollte schon auch dort unterschieden werden.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.196 Beiträge
 
Delphi 10 Seattle Enterprise
 
#10

AW: on[XYZ]-Methoden: Nicht aufrufen wenn Programmcode die Komponente ändert

  Alt 22. Jul 2013, 12:31
Danke für die Antworten

dass die Eventhandler auch nur das machen, was eine Folge der Auswahl ist. Und diese direkte Folge benötige ich dann auch, wenn ich den Wert per Quelltext selbst setze.
Ja, so sollte es eigentlich sein. Glaube ich.

Mein konkretes Beispiel:
  • Der Benutzer wählt etwas aus
  • Die TRadioGroup zeigt eine Eigenschaft des ausgewählten Dings an
  • Der Benutzer kann es ändern indem er an der TRadioGroup herumspielt

Ich könnte einen "Änderungen absenden"-Button (oder so ähnlich machen).

Oder damit leben, dass beim Setzen der TRadioGroup etwas so gesetzt wird, wie es schon ist.

Oder den onEvent-Handler kurzzeitig ausklinken.


Diese drei Möglichkeiten sehe ich
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:15 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz