Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi D7: TField.OnChange wann löst der Event aus? (https://www.delphipraxis.net/217110-d7-tfield-onchange-wann-loest-der-event-aus.html)

Bodenseematze 29. Apr 2025 14:31

D7: TField.OnChange wann löst der Event aus?
 
Hallo,

ich habe hier immer wieder Probleme mit DB-Controls, die Datenbankwerte ändern (sollen), z.B. über eine TDBRadioGroup, und das z.B. über ein OnClick über die Maske erledigen.
Eigentlich liegt dem doch im Hintergrund eine Änderung des entsprechnden Datenbank TField-Elements zugrunde.

Also dachte ich, dass es doch eigentlich viel einfacher sein müsste, die Änderungen direkt an den Datenbankfeldern zu verarbeiten anstatt an verschiedenen Stellen die Änderungen der Masken-Controls zu überwachen,

Beispiel (ist zwar für BDE, sollte aber bei anderen Datenbank-Zugriffsschichten ähnlich sein):
- es gibt ein TQuery "qryHead", dem ein SQL (SELECT) und auch entsprechende Statements für UPDATE/DELETE über ein UpdateObject zugewiesen sind.
- es gibt eine TDataSource "dsHead", der das "qryHead" als DataSet zugewiesen ist
- den Datenbank-Controls (z.B. TDBRadioGroup rgTest) ist "dsHead" als DataSource und ein DataField (z.B. "MyTest") zugewiesen
- in der IDE kann ich am "qryHead" per rechter Maustaste den "Fields Editor" aufrufen und dort dem Field "MyTest" eine Eventroutine für "OnChange" zuweisen.

Ich dachte, dass jegliche Änderungen, die z.B. über Clicks in den Checkboxen in der TBRadioGroup passieren, direkt eine Auslösung des OnChange-Events des Feldes zur Folge haben.
Nur leider ist dem nicht so und das verstehe ich nicht...

Wo liegt da mein Denkfehler bzw. wann werden die OnChange-Events ausgelöst?

Alter Mann 29. Apr 2025 15:27

AW: D7: TField.OnChange wann löst der Event aus?
 
Hi,
um bei Deinem Beispiel zu bleiben; du klickst nun einen Wert deiner Radiogroup an,
was hat sich nun in der DB geändert, dass das OnChange auslöst?
(RadioGroup = 1,2,4,8 usw.) Welcher Wert wird durch welche Routine in die DB geschrieben?

Uwe Raabe 29. Apr 2025 15:46

AW: D7: TField.OnChange wann löst der Event aus?
 
Zitat:

Zitat von Bodenseematze (Beitrag 1548348)
Wo liegt da mein Denkfehler bzw. wann werden die OnChange-Events ausgelöst?

Das passiert im TDataSet.UpdateRecord. Das wird z.B. implizit im Post oder CheckBrowseMode aufgerufen und sorgt dafür, dass alle DB-aware Controls ihre Daten in den entsprechenden Feldern abspeichern.

Siehe z.B. in TDBCheckBox.UpdateData (das wird dabei nämlich ausgeführt):
Delphi-Quellcode:
procedure TDBCheckBox.UpdateData(Sender: TObject);
var
  Pos: Integer;
  S: string;
begin
  if State = cbGrayed then
    FDataLink.Field.Clear
  else
    if FDataLink.Field.DataType = ftBoolean then
      FDataLink.Field.AsBoolean := Checked
    else
    begin
      if Checked then S := FValueCheck else S := FValueUncheck;
      Pos := 1;
      FDataLink.Field.Text := ExtractFieldName(S, Pos);
    end;
end;

himitsu 29. Apr 2025 15:49

AW: D7: TField.OnChange wann löst der Event aus?
 
Beim Zuweisen des Wertes an die TField-Komponente.

Es gibt viele Edit-Komponenten (Edit, ComboBoxen, Grids usw., aber nicht die von Delphi selbst), die nutzen ein verzögertes Rückschreiben,
also nicht bei Eingabe jedes einzelnen Buchstaben, in ein Edit (Edit.OnChange), sondern erst beim Verlassen des Edits (Edit.OnExit), damit nicht unnnötig viele Changes beim DataSet/TField eintreffen.
Bzw. hoffentlich beachten solche Komponenten auch das, was Uwe grade erwähnt hat. (wurde auch schon öfters gern mal vergessen)

Bodenseematze 29. Apr 2025 16:10

AW: D7: TField.OnChange wann löst der Event aus?
 
Zitat:

Zitat von Alter Mann (Beitrag 1548350)
Hi,
um bei Deinem Beispiel zu bleiben; du klickst nun einen Wert deiner Radiogroup an,
was hat sich nun in der DB geändert, dass das OnChange auslöst?
(RadioGroup = 1,2,4,8 usw.) Welcher Wert wird durch welche Routine in die DB geschrieben?

Es ist eine TDBRadioGroup - dort ist das Property "Items" mit mehreren Einträgen gesetzt (z.B. "Eins", "Zwei", "Drei") - diese werden als Checkboxen in der Gruppe angezeigt;
das Property "Values" ist mit den passenden Datenbankwerten gesetzt (z.B. 1, 2, 3) die zu jeder Checkbox passen.

Beim Öffnen des Query wird auch automatisch die zum Datenbankwert passende Checkbox ausgewählt angezeigt...
Und beim Anklicken einer anderen Box in der Gruppe sollte eigentlich auch der Datenbankwert passend gesetzt werden, oder nicht?

Anmerkung:
Wenn ich mir jetzt einen OnClick-Handler in die RadioGroup einbaue (was ich ja eigentlich nicht will) sehe ich dort, dass der ItemIndex auf dem korrekten (neuen) Wert sitzt; das Datenbankfeld aber noch den vorherigen Wert enthält :?
Wieso denn das?
Muss ich jetzt doch händisch dort den Field-Wert selber setzen (also z.B. "qryHeadMyField.AsInteger := 2")?

Jetzt verstehe ich gar nichts mehr...

@Uwe: werden in einer TDBRadioGroup für jeden Wert intern eine TDBCheckbox erzeugt?

Uwe Raabe 29. Apr 2025 16:19

AW: D7: TField.OnChange wann löst der Event aus?
 
Zitat:

Zitat von Bodenseematze (Beitrag 1548354)
@Uwe: werden in einer TDBRadioGroup für jeden Wert intern eine TDBCheckbox erzeugt?

Nein, aber auch bei einer TDBRadioGroup wird das Field erst auf Anforderung aktualisiert:
Delphi-Quellcode:
procedure TDBRadioGroup.UpdateData(Sender: TObject);
begin
  if FDataLink.Field <> nil then FDataLink.Field.Text := Value;
end;

Jumpy 29. Apr 2025 16:31

AW: D7: TField.OnChange wann löst der Event aus?
 
War es nicht so, dass wenn man in den DB-Aware Controls etwas ändert, dann ändert man das in der Datasource und gibt die Änderung somit auch an das Dataset (hier die Query) weiter, die dann in den State dsEdit gesetzt wird. Die Änderung wird aber noch nicht an die Datenbank weiter gegeben. Das passiert erst mit dem Absetzen eines Query.Post Befehls.

Ich bin jetzt nicht mehr sicher, aber konnte man nicht auch eine Property so setzen, dass jede Änderung autom. direkt gepostet wird, dann wäre das explizite "if Query.State=dsEdit then Query.Post" nicht nötig.

Bodenseematze 29. Apr 2025 16:32

AW: D7: TField.OnChange wann löst der Event aus?
 
Arrrglll - ich bin mal wieder auf einen Spezialfall reingefallen.

In dem von mir skizzierten Beispiel war eine Information nicht enthalten:
Beim angesprochenen TField handelt es sich in dem Fall um ein TFloatField (weil die Datenbank-Spalte (leider) ein "DECIMAL(18,3)"-Wert ist).
Sie enthält zwar nur die möglichen Werte 0, 1, 2 - das sind aber eben "offiziell" Kommawerte...
Und da scheint das automatische Setzen des Wertes bei einer TDBRadioGroup nicht zu funktionieren (der umgekehrte Weg, d.h. vom TFloatField-Wert zur Auswahl der richtigen Checkbox funktioniert komischerweise).

Bei einem Test mit einem TIntegerField als Basis für die TDBRadioGroup funktioniert das - und im testweise angelegten OnClick-Handler der TDBRadioGroup ist der TField-Wert bereits auf den ausgewählten Wert gesetzt (obwohl der OnChange-Handler erst danach aufgerufen wird).

Leider kann / darf ich die Datenbankstruktur nicht anpassen, um das zu korrigieren - muss mir jetzt also überlegen, wie ich das (besser) löse... :|


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:14 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