![]() |
DBEdits rufen sich gegenseitig auf
Hallo,
es werden: Anfangszeit(TTime) | Stunden(Int) | Minuten(Int) | Endezeit(TTime) berechnet. Im Form ist ein cxGrid(DevEx) und in einem Detailfeld das Ganze noch mal in Editfeldern. Zeiten in cxDBDateTimeEdit, Stunden/Minuten in cxDBSpinEdit. Die Änderungen in einem der Edits oder im Grid sollen dem Benutzer sofort angezeigt werden, das heißt, sie werden in "onEditValueChanged" berechnet und den anderen Èdits zugewiesen. Es stehen OnChange, OnEditValueChanged und OnValidate zur Verfügung. Jetzt ist das Problem, dass sie sich gegenseitig aufrufen = Endlosschleife. Mir fällt nichts ein, wie ich das unterbinen kann. Wenn ich nur das Grid benutze und die Berechnungen aus den Edits rausnehme dann geht's. |
AW: DBEdits rufen sich gegenseitig auf
Guck Dir mal in der Hilfe .LockChangeEvents der Controls an.
|
AW: DBEdits rufen sich gegenseitig auf
Da du die Berechnung vom Kontext abhängig machst
(z.B.
musst du dir wohl oder übel auch den Kontext merken und nicht einfach nur drauf los rechnen ;) Den Kontext (aktives Feld) bekommt man aber auch über ![]() Eine andere Möglichkeit wäre, die Berechnung entsprechend zu unterbinden, wenn man schon berechnet:
Delphi-Quellcode:
type
TForm1 = class( TForm ) Anfang_SpinEdit : TSpinEdit; Ende_SpinEdit : TSpinEdit; Interval_SpinEdit : TSpinEdit; // alle 3 Felder rufen bei OnChange diese Methode auf procedure ControlChange( Sender : TObject ); private FCalculating : Boolean; procedure DoCalculate( Context : TObject ); public { Public-Deklarationen } end; var Form1 : TForm1; implementation {$R *.dfm} { TForm1 } procedure TForm1.ControlChange( Sender : TObject ); begin // Wenn die Berechnung schon läuft, dann wieder raus hier if FCalculating then Exit; // Berechnungs-Flag setzen FCalculating := True; try // Berechnung durchführen DoCalculate( Sender ); finally // Berechnungs-Flag entfernen FCalculating := False; end; end; procedure TForm1.DoCalculate( Context : TObject ); begin // abhängig vom Context die Berechnung durchführen if Context = Anfang_SpinEdit then begin Ende_SpinEdit.Value := Anfang_SpinEdit.Value + Interval_SpinEdit.Value; end else if Context = Ende_SpinEdit then begin Interval_SpinEdit.Value := Ende_SpinEdit.Value - Anfang_SpinEdit.Value; end else if Context = Interval_SpinEdit then begin Ende_SpinEdit.Value := Anfang_SpinEdit.Value + Interval_SpinEdit.Value; end; end; |
AW: DBEdits rufen sich gegenseitig auf
Mal doof gefragt (denn ich hab wahrsch. die Frage nur halb verstanden): Wenn das doch DBEdits usw. sind. Wenn ich da irgendwas ändere, ändert das nicht auch die darunterliegende Datasource, so dass die Änderungen auch in anderen Edits, die dasselbe anzeigen, autom. angezeigt werden?
Alternativ zu dem sicher sinnvollen Ansatz von Sir Rufo kann man auch immer die Eventhandler abschalten, um so Zirkelgeschichten aufzulösen und dann nachher wieder anschalten. |
AW: DBEdits rufen sich gegenseitig auf
Zitat:
Zitat:
Prominentes Beispiel ist ![]() |
AW: DBEdits rufen sich gegenseitig auf
Sir Rufo, Dein Vorschlag (Kontext) hat funktioniert. Danke.
Allerdigs nicht mit dem Eintrag der Werte in die Value-Eigenschaft, sondern direkt in die Datenbank (FieldByName ...). Als angenehmer Nebeneffekt brauche ich die Berechnungen nicht im Grid zu wiederholen. Über die Datenbank werden Grid und Edits getriggert, egal ob ich die Edits verändere oder die Werte im Grid, die Funktionen laufen immer in den Edits ab. (Habt ihr meine Erklärung verstanden? Ich kanns nicht besser erklären.) Nochmal Danke.
Delphi-Quellcode:
...
// STUNDEN geändert else if TimeContext = sedStunden then begin dBegin := FieldByName('TimeBegin').AsFloat; (* dStd := sedStunden.EditValue;*) dStd := FieldByName('Anzahl_std').AsInteger; iMin := FieldByName('Anzahl_min').AsInteger; x := (dStd/24) + (iMin / 1440); // Zeitwerte dezimal 24:00 = 1 , 12:00 = 0.5 dEnde := dBegin + x; x := ((dStd*60) + iMin)/60; // Summe in Minuten /60 = Summe in Stunden iStd := Trunc(x); iMin := Round(Frac(x) * 60); if State IN [dsInsert,dsEdit] then Begin FieldByName('TimeEnde').AsFloat := dEnde; FieldByName('Anzahl_std').AsInteger := iStd; FieldByName('Anzahl_min').AsInteger := iMin; End; end ... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:27 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