![]() |
verschränke ToggleBoxes
Hallo zusammen,
folgender Code:
Delphi-Quellcode:
Ich habe zwei ToggleBoxes welche jeweils abwechselnd Checked bzw. nicht Checked sein sollen. Damit nicht der Fall Auftritt, dass beide Checked oder nicht Checked sind, gibt es die if abfragen welche eine solche Kombination verhüten sollen. Ich hatte die Prozeduren ursprünglich im Change- Event, allerdings nicht beachtet, dass OnChange auch bei Veränderungen durch das Programm ausgelöst wird, sodass es mir gelungen ist, eine "doppelt gewundene Endlosschleife" zu programmieren :lol:, welche irgendwann (nach ca. 1/2 sekunde) in einem Zugriffsfehler endet (Warum?). Jetzt wollte ich die Methoden über den Objektinspektor neu zuweisen, sodass jetzt das Klick- Ereignis diese auslöst. Allerdings besteht nach wie vor der Fehler. Kann es sein, dass Lazarus die alten Verbindungen irgendwie nicht gelöscht hat, obwohl ich sie im Objektinspektor entfernt habe?
procedure TForm1.GehevorChange(Sender: TObject);
begin if Gehevor.Checked = false then begin Gehevor.Checked:= true; exit; end; Gehezurueck.Checked:= false; end; procedure TForm1.GehezurueckChange(Sender: TObject); begin if Gehezurueck.Checked = false then begin Gehezurueck.Checked:= true; exit; end; Gehevor.Checked:= false; end; |
AW: verschränke ToggleBoxes
Es ist eher simpel zu lösen:
Erstelle dir eine Eigenschaft vom Typ
Delphi-Quellcode:
mit einer Setter-Methode:
Boolean
Delphi-Quellcode:
procedure TForm1.SetStatus( const Value : Boolean );
begin if FStatus <> Value then begin FStatus := Value; GeheVor.Checked := FStatus; GeheZurueck.Checked := not FStatus; end; end; procedure TForm1.GehevorChange(Sender: TObject); begin SetStatus( GeheVor.Checked ); end; procedure TForm1.GehezurueckChange(Sender: TObject); begin SetStatus( not GeheZurueck.Checked ); end; |
AW: verschränke ToggleBoxes
Liste der Anhänge anzeigen (Anzahl: 2)
Zitat:
![]() ![]() Den Begriff ToggleBox scheint es im Zusammenhang mit Delphi nicht wirklich zu geben. Es gibt aber ToggleButtons, z.B. bei den Jedis (siehe Bild 2). |
AW: verschränke ToggleBoxes
@Sir Rufo: Rufst Du innerhalb der Klasse immer explizit den Setter der Eigenschaft auf, oder ist das ein Versehen? Ich würde das nie machen. Der Setter ist eigentlich privater als privat und sollte noch nicht einmal innerhalb der Klasse aufgerufen werden.
|
AW: verschränke ToggleBoxes
Warum ist der Setter privater als privat? Es gibt Sprachen, in denen ist der sogar der einzige Weg auf private Felder zuzugreifen.
Warum sollte man interne Prüfungen auf Wertebereiche, welche im Setter stehen an anderer Stelle wiederholen sollen? |
AW: verschränke ToggleBoxes
Zitat:
@SirRufo: Ich möchte nach Möglichkeit sofort die Änderungsinformation an eine weitere Klasse weiterreichen, deswegen wollte ich kein zusätzliches Feld deklarieren und die gesamte Abfrage innerhalb des OnChange bzw. OnClick durchführen. Was mich immer noch wundert, ist, dass er das Ereignis immer noch als OnChange verwendet, obwohl ich es im Objektinspektor auf OnClick umgestellt habe. |
AW: verschränke ToggleBoxes
Zitat:
|
AW: verschränke ToggleBoxes
Ja, alles ist ordnungsgemäß so eingestellt, dass es funktionieren sollte. :roll: Anscheinend gibt es da einen Bug in der Zuweisung der Events im Objektinspektor oder ich mache irgendwas anderes falsch.
Der Fehler tritt auch in der Form auf, dass er die "Schleife" ein paar mal durchrattert und danach den Fehler eines falschen Zugriffs schmeißt. Wisst ihr, warum er das tut? |
AW: verschränke ToggleBoxes
Zitat:
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. @Dejan Vu Es ging mir nur um das Prinzip, wie man das zusammenfassen kann. Richtig, richtig, wird das z.B. mit einem ViewModel, wo jeder Button seinen Status auslesen und setzen kann und zwar unabhängig voneinander. Das ViewModel kümmert sich nun intern um die entsprechenden logischen Zusammenhänge und übergibt den resultierenden Wert an die Datenklasse oder wohin auch immer. ViewModel:
Delphi-Quellcode:
View:
type
TFooViewModel = class( TViewModelBase ) private FStatus: Boolean; FButton2Checked: Boolean; FButton1Checked: Boolean; procedure SetStatus( const Value: Boolean ); 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; end; function TFooViewModel.GetButton2Checked: Boolean; begin Result := not FStatus; end; procedure TFooViewModel.SetButton1Checked( const Value: Boolean ); begin SetStatus( Value ); end; procedure TFooViewModel.SetButton2Checked( const Value: Boolean ); begin SetStatus( not Value ); end; procedure TFooViewModel.SetStatus( const Value: Boolean ); begin if FStatus <> Value then begin FStatus := Value; OnPropertyChanged( ['Button1Checked', 'Button2Checked'] ); end; end;
Delphi-Quellcode:
type
TFooViewForm = class( TBaseForm ) Switch1: TSwitch; Switch2: TSwitch; procedure Switch1Switch( Sender: TObject ); procedure Switch2Switch(Sender: TObject); private FViewModel: Ref<TFooViewModel>; protected procedure ViewModelPropertyChanged( Sender: TObject; const e: TPropertyChangedArgs ); override; public procedure SetViewModel( AViewModel: TViewModelBase ); override; end; var FooViewForm: TFooViewForm; implementation {$R *.fmx} { TFooViewForm } procedure TFooViewForm.SetViewModel( AViewModel: TViewModelBase ); begin FViewModel := AViewModel as TFooViewModel; inherited; end; procedure TFooViewForm.Switch1Switch( Sender: TObject ); begin inherited; if FViewModel.IsAssigned then FViewModel.Reference.Button1Checked := Switch1.IsChecked; end; procedure TFooViewForm.Switch2Switch(Sender: TObject); begin inherited; if FViewModel.IsAssigned then FViewModel.Reference.Button2Checked := Switch2.IsChecked; end; procedure TFooViewForm.ViewModelPropertyChanged( Sender: TObject; const e: TPropertyChangedArgs ); begin inherited; if FViewModel.IsAssigned then begin if e.Match( 'Button1Checked' ) then Switch1.IsChecked := FViewModel.Reference.Button1Checked; if e.Match( 'Button2Checked' ) then Switch2.IsChecked := FViewModel.Reference.Button2Checked; end; end; |
AW: verschränke ToggleBoxes
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; Zitat:
Ich kenne keine Programmiersprache, bei der direkte Aufruf des Setters "sogar der einzige Weg" ist, um "auf private Felder zuzugreifen". Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:57 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