AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

verschränke ToggleBoxes

Ein Thema von TForm1 · begonnen am 18. Jan 2015 · letzter Beitrag vom 19. Jan 2015
Antwort Antwort
Seite 2 von 2     12   
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.858 Beiträge
 
Delphi 11 Alexandria
 
#11

AW: verschränke ToggleBoxes

  Alt 18. Jan 2015, 11:39
Zitat:
Ich kenne keine Programmiersprache, bei der direkte Aufruf des Setters "sogar der einzige Weg" ist, um "auf private Felder zuzugreifen".
Von außen schon, in Sprachen ohne Properties wie z.B. Java.

Im Setter kann auch etwas mehr als "nur" die Zuweisung erfolgen, deshalb kann es auch intern sinnvoll sein den Setter aufzurufen.

Will ich sicherstellen, das weitere Contraints erfüllt werden, welche im Setter überprüft werden -> Aufruf Setter

Will ich den Wert auf jedenfall setzen -> direkter Zugriff auf Feld.
Markus Kinzler
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#12

AW: verschränke ToggleBoxes

  Alt 18. Jan 2015, 11:47
Ich sehe gerade, das im Code die Methode 'SetStatus' als 'Setter' bezeichnet wird, was er ja gar nicht ist, denn wo keine Property, da auch kein Setter. Insofern führt das dann auch mal zu Misverständnissen. Richtig(er) sollte es also sein, eine private Property 'Status' einzuführen. Denn sonst sieht man ja nicht, das 'FStatus' und 'SetStatus' etwas miteinander zu zun haben.
Delphi-Quellcode:
Type
  TFoo = class
    property Status : boolean Read FStatus Write SetStatus;
  end;
Ah sehr schön, dass du meinen Text aufmerksam durchgelesen hast:
Erstelle dir eine Eigenschaft vom Typ Boolean mit einer Setter-Methode:
Soll ich es größer und bunter gestalten? Soll ich explizit noch dazu schreiben
Zitat:
Ich gehe mal davon aus, dass jeder weiß was eine Eigenschaft ist und wie man die erstellt, so dass diese eine Setter-Methode hat. Darum zeige ich hier jetzt nur die Setter-Methode. Die IDE erstellt zu einer Eigenschaft auch automatisch ein Feld, das gleichlautend wie die Eigenschaft ist, mit einem vorangestellten F.
Also eine Eigenschaft property Status : Boolean; bekommt durch die Code-Vervollständigung automatisch ein privates Feld FStatus: Boolean; und eine private Setter-Methode procedure SetStatus( const Value : Boolean );
Sollte ich vorsichtshalber auch noch vermerken "Einatmen - Ausatmen! Und hübsch in dieser Reihenfolge und kontinuierlich!"

Jetzt mal wieder an die normaldenkende Allgemeinheit (jeder der sich dazu zählt, darf sich angesprochen fühlen)

Um aus diesen Toggle-buttons jetzt einen TriState zu machen, ändert man einfach das ViewModel ab (macht natürlich nur Sinn, wenn diese Information im Daten-Modell auch verwertet werden kann, logisch - aber genau das sind ja die Änderungen, die immer wieder auf einen zukommen) und schwups, ohne eine Änderung an der View, passiert alles wie gewünscht:
Delphi-Quellcode:
type
  TStatus = ( None, Prev, Next );

  TFooViewModel = class( TViewModelBase )
  private
    FStatus: TStatus;
    FButton2Checked: Boolean;
    FButton1Checked: Boolean;
    procedure SetStatus( const Value: TStatus );
    procedure SetButton1Checked( const Value: Boolean );
    procedure SetButton2Checked( const Value: Boolean );
    function GetButton1Checked: Boolean;
    function GetButton2Checked: Boolean;
  public

    property Button1Checked: Boolean read GetButton1Checked write SetButton1Checked;
    property Button2Checked: Boolean read GetButton2Checked write SetButton2Checked;
  end;

implementation

{ TFooViewModel }

function TFooViewModel.GetButton1Checked: Boolean;
begin
  Result := FStatus = TStatus.Prev;
end;

function TFooViewModel.GetButton2Checked: Boolean;
begin
  Result := FStatus = TStatus.Next;
end;

procedure TFooViewModel.SetButton1Checked( const Value: Boolean );
begin
  if GetButton1Checked <> Value
  then
    if Value
    then
      SetStatus( TStatus.Prev )
    else
      SetStatus( TStatus.None );
end;

procedure TFooViewModel.SetButton2Checked( const Value: Boolean );
begin
  if GetButton2Checked <> Value
  then
    if Value
    then
      SetStatus( TStatus.Next )
    else
      SetStatus( TStatus.None );
end;

procedure TFooViewModel.SetStatus( const Value: TStatus );
begin
  if FStatus <> Value
  then
    begin
      FStatus := Value;
      OnPropertyChanged( ['Button1Checked', 'Button2Checked'] );
    end;
end;
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
TForm1

Registriert seit: 11. Jan 2014
128 Beiträge
 
FreePascal / Lazarus
 
#13

AW: verschränke ToggleBoxes

  Alt 18. Jan 2015, 20:07
Dann packe die Logik doch einfach in diese Klasse oder schalte da einfach eine Klasse davor, die diese Logik innehat. Was man nicht macht, ist die Logik in der Form/View so an direkt mit den Controls zu verkoppeln, wie du das gemacht hast.
Nagut, überzeugt . Dennoch ist damit mein Problem nicht gelöst, denn es wird immer noch der OnChange aufgerufen, was ja eigentlich bei deinem Code kein Problem darstellen sollte, denn durch die Abfrage if FStatus <> Value , sollte bei dem ungewünschten Aufruf der folgende Code einfach übergangen werden. Dennoch tritt bei mir der Fall auf, wenn ich zurück wechseln möchte von FStatus:= false zu true, dass dann aus irgend einem Grund (ich habe keine Ahnung, aus Welchem) trotzdem in den if-Block gegangen wird und somit eine weitere Verkettung sozusagen "rekursiver" Aufrufe erfolgt. Hat jemand eine Idee, warum das passiert?

Im Prinzip könnte ich ja einfach komplett neue Methoden direkt als OnClick anlegen und den alten Code kopieren, aber mich interessiert es zu wissen, warum trotz der neuen Verknüpfung immer noch OnChange aufgerufen wird.
Der Fehler sitzt immer vor dem Computer...
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#14

AW: verschränke ToggleBoxes

  Alt 18. Jan 2015, 20:55
Dann zeig doch mal deinen Code denn nur anhand deiner Beschreibung kann man da nichts finden
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
TForm1

Registriert seit: 11. Jan 2014
128 Beiträge
 
FreePascal / Lazarus
 
#15

AW: verschränke ToggleBoxes

  Alt 18. Jan 2015, 23:25
...Beim Schreiben viel mir gerade der Fehler auf, wo der Fehler lag...war ein einfacher Tippfehler Der Code funktioniert jetzt prima

Allerdings bleibt jetzt dennoch das Grundübel, nämlich, dass beim OnClick gleichzeitig das OnChange mit aufgerufen wird, obwohl ich das im Objektinspektor geändert habe. Das war eigentlich auch meine Ausgangsfrage. Weiß jemand über einen Bug in Lazarus bescheid, bei dem die Verknüpfungen der Events bei Löschen trotzdem bestehen bleiben?
Der Fehler sitzt immer vor dem Computer...
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#16

AW: verschränke ToggleBoxes

  Alt 19. Jan 2015, 00:03
Ok, letzte Gelegenheit, dann frag einfach nicht mehr, bzw. ich bin solange raus bis:
Dann zeig doch mal deinen Code denn nur anhand deiner Beschreibung kann man da nichts finden
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
TForm1

Registriert seit: 11. Jan 2014
128 Beiträge
 
FreePascal / Lazarus
 
#17

AW: verschränke ToggleBoxes

  Alt 19. Jan 2015, 18:39
Oh. Dann habe ich mich wohl nicht verständlich ausgedrückt. Der Code funktioniert jetzt wunderbar, alles kein Problem. Ich kann ihn totzdem noch mal posten, auch wenn es nichts anderes ist, als bereits oben schon:
Delphi-Quellcode:
procedure TForm1.GehevorClick(Sender: TObject); //Diese Methoden sind beide OnClick, ich habe sie zuvor von OnChange auf OnClick geändert. Allerdings werden sie trotzdem immer noch als OnChange aufgerufen, wenn die Eigenschaft Checked der ToggleBox unten* neu zugewiesen wird.
begin
  SetRichtung(Gehevor.Checked);
end;

procedure TForm1.GehezurueckClick(Sender: TObject);
begin
 SetRichtung(not Gehezurueck.Checked);
end;

procedure TForm1.SetRichtung(const aValue: boolean);
begin
  if FRichtung <> aValue then
  begin
    FRichtung:= aValue;
    Gehevor.Checked:= FRichtung; //*Hier werden wieder die Methoden oben aufgerufen, obwohl diese als OnClick ja nicht aufgerufen werden sollten.
    Gehezurueck.Checked:= not FRichtung;
  end;
end;
Der Code funktioniert ohne Fehler und tut was er soll, da die if- Verzweigung davor schützt, dass eine "Endlosschleife" entsteht. Im Prinzip ist es also jetzt nur noch ein Schönheitsfehler, bzw, wie ich vermute Bug in Lazarus, den ich aber auch gerne verstehen würde. Ich habe also im Objektinspektor die Property OnChange geleert und OnClick befüllt und schließlich noch von Hand auf Gehevor/zurückClick umbenannt, dann dürfte die Methode doch nicht bei OnChange aufgerufen werden, oder?
Der Fehler sitzt immer vor dem Computer...
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#18

AW: verschränke ToggleBoxes

  Alt 19. Jan 2015, 20:33
Aha, das ist aber ein völlig normales Verhalten und sollte auch so dokumentiert sein. Eine Änderung der Eigenschaft Checked löst auch einen OnClick-Event aus. Es kann auch genauso gut sein, dass beim Setzen der Eigenschaft Checked immer OnClick gefeuert wird und OnChange nur dann kommt, wenn Changed vorher anders war. Genauso gut kann es sogar (auch wenn es falsch wäre -> Bug) sein, dass beide Events immer gefeuert werden, wenn der Eigenschaft Checked ein Wert zugewiesen wird.

Das genaue Verhalten kann man sich im Quelltest der Komponente aber sehr schön anschauen, dann weiß man was da genau passiert.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
TForm1

Registriert seit: 11. Jan 2014
128 Beiträge
 
FreePascal / Lazarus
 
#19

AW: verschränke ToggleBoxes

  Alt 19. Jan 2015, 22:25
Tatsächlich! OnClick wird auch dann ausgelöst, wenn Checked gesettet wird. Irgendwie bin ich davon ausgegangen, dass OnClick logischerweise nur dann ausgelöst wird, wenn man darauf klickt . Dann hat ja alles seine Richtigkeit, vielen Dank für die Info

Und drauf gekommen, mal im Quellcode nachzuschauen bin ich natürlich auch nicht.
Der Fehler sitzt immer vor dem Computer...
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


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 21:15 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz