Reagieren darauf das ein Benutzer einen Wert aus der Combobox Liste ausgewählt hat

Rund um die LCL und andere Komponenten
corpsman
Beiträge: 1147
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus SVN Trunk, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Reagieren darauf das ein Benutzer einen Wert aus der Combobox Liste ausgewählt hat

Beitrag von corpsman »

Hallo Zusammen,

Ich bastle gerade eine Anwendung bei der der Benutzer bei einer Combobox etwas auswählen kann. Je nachdem was er ausgewählt hat möchte ich dann Reagieren

Laut google gibt es einen DropDownClosed Event :
Den Kann ich aber irgendwie bei der LCL nicht finden.

Als Alternative fällt mir nur noch der "OnChanged" ein, aber der wird ja auch immer gefeuert wenn der User etwas im textfeld tippt, also eigentlich viel zu oft...

Hat da noch jemand ne Idee ?
--
Just try it

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 728
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Winux (L 2.0.11 FPC 3.2)
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Reagieren darauf das ein Benutzer einen Wert aus der Combobox Liste ausgewählt hat

Beitrag von fliegermichl »

TComboBox.OnCloseUp?

Benutzeravatar
Winni
Beiträge: 503
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.06, fpc 3.04
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Reagieren darauf das ein Benutzer einen Wert aus der Combobox Liste ausgewählt hat

Beitrag von Winni »

fliegermichl hat geschrieben:
Do 24. Sep 2020, 12:14
TComboBox.OnCloseUp?
Hi!

OnCloseUp geht dafür auch.

Eigentlich dafür gedacht is wohl OnSelect:

Code: Alles auswählen

procedure TForm1.ComboBox1Select(Sender: TObject);
begin
   showMessage (ComboBox1.Items[ComboBox1.ItemIndex]);
end; 
OnSelect hat den Vorteil, dass ein Item ausgewählt ist .

OnCloseUp kann auch die DropDownList zumachen, ohne dass was ausgewählt ist.
Lästigerweise muss man dann erst fragen, ob der ItemIndex >= 0 ist, bevor man weitere Aktionen auslöst.

Winni

Warf
Beiträge: 1524
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: MacOS | Win 10 | Linux
CPU-Target: x86_64
Wohnort: Aachen

Re: Reagieren darauf das ein Benutzer einen Wert aus der Combobox Liste ausgewählt hat

Beitrag von Warf »

fliegermichl hat geschrieben:
Do 24. Sep 2020, 12:14
TComboBox.OnCloseUp?
Funktioniert das denn auch wenn man per tastatur den inhalt der Box wechselt (pfeiltasten)?

corpsman
Beiträge: 1147
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus SVN Trunk, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: Reagieren darauf das ein Benutzer einen Wert aus der Combobox Liste ausgewählt hat

Beitrag von corpsman »

@Winni,

thx das Onselect ist genau was ich brauche, das geht auch via Tastatur.

Danke
--
Just try it

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 728
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Winux (L 2.0.11 FPC 3.2)
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Reagieren darauf das ein Benutzer einen Wert aus der Combobox Liste ausgewählt hat

Beitrag von fliegermichl »

Hi,

das ist insgesamt eine Thematik, die meiner Meinung nach schon immer etwas stört.

Wann macht man beispielsweise sinnvoll die Prüfung eines Eingabewertes in einem TEdit?

mse hat dafür den Event OnDataEntered. Wenn man einen Wert eingegeben hat und Enter drückt, wird dieser Event gefeuert.
Ein weiteres Enter löst dann das vordefinierte Verhalten aus. (z.B. ButtonClick des Default Button)

So etwas fehlt in Lazarus.

Gruß
Michael

corpsman
Beiträge: 1147
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus SVN Trunk, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: Reagieren darauf das ein Benutzer einen Wert aus der Combobox Liste ausgewählt hat

Beitrag von corpsman »

@Fliegermichl

*g* jetzt wird es Philosophisch.
Den Data entered Event kannst du ja einfach machen in dem du im OnKeypress auf #13 prüfst und dann den Button.Click von hand auslöst. Funktioniert bei mir wunderbar. Ein zweites mal #13 zu drücken um dann einen Button aus zu lösen würde mich stören ..

Zurück zur Combobox:
Meine Bishere Lösung war, auf das OnChange Event zu reagieren, was auch geht aber "zu häufig" ist. das Select Event reduziert die Aufrufhäufigkeit und spart damit einfach nur Rechenzeit. Ich hatte das einfach nur nicht gesehen ;)
--
Just try it

Benutzeravatar
Winni
Beiträge: 503
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.06, fpc 3.04
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Reagieren darauf das ein Benutzer einen Wert aus der Combobox Liste ausgewählt hat

Beitrag von Winni »

fliegermichl hat geschrieben:
Fr 25. Sep 2020, 07:57
Hi,

das ist insgesamt eine Thematik, die meiner Meinung nach schon immer etwas stört.

Wann macht man beispielsweise sinnvoll die Prüfung eines Eingabewertes in einem TEdit?

mse hat dafür den Event OnDataEntered. Wenn man einen Wert eingegeben hat und Enter drückt, wird dieser Event gefeuert.
Ein weiteres Enter löst dann das vordefinierte Verhalten aus. (z.B. ButtonClick des Default Button)

So etwas fehlt in Lazarus.

Gruß
Michael

Hi!

Um gültige Werte schon beim Tastendruck zu überprüfen: Dafür gibt's KeyPress/KeyDown/KeyUp:

Man baut sich ein Set von erlaubten Werten, und wenn der Key-Wert nicht im Set ist, wird der Wert 0 bzw #0.

Ein Set für KeyDown für die Eingbe von Integer-Werten sieht dann so aus:

Code: Alles auswählen

Const
IntSet =[VK_0..VK9, VK_Left,VK_right, VK_Back,VK_Delete, VK_OEM_MINUS]

Dann entfällt die ganze Arie mit OnDataEntered:
Die Werte im Edit.text sind immer im legalen Bereich.

Lästig ist dabei die Überprüfungen von Minus bzw Dezimal-Punkt bei Floats:
Überprüfen ob sie nur maximal einmal vorhanden sind und an der richtigen Stelle stehen.

Letzteres kann man sich sparen, wenn man nach jedem KeyDown Folgendes macht:

Code: Alles auswählen

val (Edit1.text,myInteger,error);
Wenn error <> 0 dann den gespeicherten letzten Wert nehmen und Key auf Null setzen .

Ein weiterer Fallstrick ist die Eingabe von Exponential-Eingaben bei Floats.
Tippt man ein E - weil man 123E45 eingeben will - so ist das in dem Moment kein
valider Wert - muss man gesondert behandeln.

Winni

PS.: OnSelect ist auch schwer zu finden. Da muss man ja im OI runterscrollen ...

Winni

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 728
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Winux (L 2.0.11 FPC 3.2)
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Reagieren darauf das ein Benutzer einen Wert aus der Combobox Liste ausgewählt hat

Beitrag von fliegermichl »

Hi,

ja genau deswegen doch. So kann man den Anwender erst mal tippen lassen was er will und dann bei OnDataEntered wird geprüft. Einmal fertig.

Benutzeravatar
theo
Beiträge: 8539
Registriert: Mo 11. Sep 2006, 19:01

Re: Reagieren darauf das ein Benutzer einen Wert aus der Combobox Liste ausgewählt hat

Beitrag von theo »

Winni hat geschrieben:
Fr 25. Sep 2020, 10:21
PS.: OnSelect ist auch schwer zu finden. Da muss man ja im OI runterscrollen ...
Ja, das muss ich schon auch sagen. Das Vorgehen von corpsman via Google und Microsoft ist mir ein Rätsel.
Es stehen doch alle zur Verfügung stehenden Events im OI und da ist auch noch erklärt, was die tun.
@corpsman: Was müsste die IDE denn noch liefern, damit du dich nicht genötigt siehst, bei Microsoft anzuklopfen?
Irgend etwas fehlt Lazarus wohl, aber was?
Dateianhänge
lazobjinsp.png
lazobjinsp.png (44.11 KiB) 806 mal betrachtet

Benutzeravatar
Winni
Beiträge: 503
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.06, fpc 3.04
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Reagieren darauf das ein Benutzer einen Wert aus der Combobox Liste ausgewählt hat

Beitrag von Winni »

fliegermichl hat geschrieben:
Fr 25. Sep 2020, 10:30
Hi,

ja genau deswegen doch. So kann man den Anwender erst mal tippen lassen was er will und dann bei OnDataEntered wird geprüft. Einmal fertig.
Hi!

Das finde ich lästig: erst tippen und dann merken, dass es Mist ist.
Und wieder Edit anklicken, löschen und den richten Key eingeben:
Viel zu viel Gezappel.
Dann doch lieber gleich die Eingaben abfangen und überprüfen:
Das spart viel Tipparbeit.

Das hab ich eingeführt, nachdem ich mit den Kollegen von der
Buchhaltung gesprochen habe. Und sie beim Tippen beobachtet habe.
Was da so an Unmengen von Daten - meist Zahlen - so an einem Tag
weggehackt werden muss. Weil die meisten Rechnungen in D immer noch
als Papier ankommen. In dieser Digital-Bananen-Republik.

Winni

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 728
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Winux (L 2.0.11 FPC 3.2)
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Reagieren darauf das ein Benutzer einen Wert aus der Combobox Liste ausgewählt hat

Beitrag von fliegermichl »

Hi,

andererseits schauen viele während des Tippens auf die Tastatur und nicht zum Bildschirm.
Jede der Methoden mag ihre Vor- und Nachteile haben.

Gruß
Michl

wp_xyz
Beiträge: 3462
Registriert: Fr 8. Apr 2011, 09:01

Re: Reagieren darauf das ein Benutzer einen Wert aus der Combobox Liste ausgewählt hat

Beitrag von wp_xyz »

Ich habe früher auch immer versucht, die Fehler gleich bei der Eingabe im KeyDown/Up/Press abzufangen. Aber das endet in lauter Problemen: die von winni schon angesprochene vorübergehend halbfertige Exponentialdarstellung, oder Leereingabe (als Default-Wert). Auch die Fehlerprüfung bei einem "OnDataEntered" (bei TEdit heißt das: OnEditingDone) hat's in sich: Was wenn der User in dem Formular während eine (ungültigen) Eingabe festellt, dass er das modale Formular lieber mit ESC/Cancel schließen will, und anderswo noch etwas zu suchen. Bei dem ESC soll aber die Eingabe ohnehin ignoriert werden, so dass gar keine Fehlerprüfung nötig ist.

Daher prüfe ich jetzt nur noch beim Schließen des Formulars oder beim Drücken des Buttons, bevor die Information ausgewertet wird. Dadurch werden die Fehlermeldungen während des Tippens oder beim Drücken von Cancel vermieden. Außerdem kann man auch gleich logische Fehler erkennen: Ist das Minimum kleiner als das Maximum? Ist ein Feld leer, obwohl der Wert benötigt wird? Wird ein Edit geprüft, das im aktuellen Kontext gar nicht nötig und sichtbar ist? Hier eine Fehlermeldung auszulösen, wäre extrem verwirrend.

Es gibt immer eine Eingabeprüfungs-Funktion, etwa Validate(), die ein TRUE bei gültiger Eingabe, andernfalls ein FALSE zurückgibt, wobei dann auch noch in den out-Parametern "AControl" das fehlerhafte Eingabeelement und in "AMsg" eine Fehlermeldung stehen. In der Click-Behandlung des OK-Buttons wird Validate() aufgerufen: Ist der Funktionswert FALSE, wird der Fokus auf das übergebenen Control gesetzt, die erzeugte Fehlermeldung angezeigt, sowie das ModalResult des Eingabeformulars auf mrNone gesetzt, um zu verhindern, dass dieses geschlossen wird.

Hier ein Ausschnitt aus LazStats, das ich z.Zt. überarbeite:

Code: Alles auswählen

function TDistribFrm.Validate(out AMsg: String; out AControl: TWinControl): boolean;
begin
  Result := false;
  if AlphaEdit.Text = '' then
  begin
    AMsg := 'Input required.';
    AControl := AlphaEdit;
    Alpha := NaN;
    exit;
  end;
  if not TryStrToFloat(AlphaEdit.Text, Alpha) or (Alpha <= 0) or (Alpha >= 1.0) then
  begin
    AMsg := 'Numerical value between 0 and 1 required.';
    AControl := AlphaEdit;
    Alpha := NaN;
    exit;
  end;

  if tChk.Checked or ChiChk.Checked or FChk.Checked then
  begin
    if DF1Edit.Text = '' then
    begin
      AMsg := 'Input required.';
      AControl := DF1Edit;
      DF1 := -1;
      exit;
    end;
    if not TryStrToInt(DF1Edit.Text, DF1) or (DF1 <= 0) then
    begin
      AMsg := 'Positive numerical value required.';
      AControl := DF1Edit;
      DF1 := -1;
      exit;
    end;
  end;

  if FChk.Checked then
  begin
    if DF2Edit.Text = '' then
    begin
      AMsg := 'Input required.';
      AControl := DF2Edit;
      DF2 := -1;
      exit;
    end;
    if not TryStrToInt(DF2Edit.Text, DF2) or (DF2 <= 0) then
    begin
      AMsg := 'Positive numerical value required.';
      AControl := DF2Edit;
      DF2 := -1;
      exit;
    end;
  end;

  Result := true;
end;

procedure TDistribFrm.ComputeBtnClick(Sender: TObject);
var
  msg: String;
  C: TWinControl;
  ok: Boolean;
begin
  if not Validate(msg, C) then
  begin
    C.SetFocus;
    MessageDlg(msg, mtError, [mbOK], 0);
    exit;
  end;
  ....
Zuletzt geändert von wp_xyz am Sa 26. Sep 2020, 13:34, insgesamt 1-mal geändert.

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 728
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Winux (L 2.0.11 FPC 3.2)
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Reagieren darauf das ein Benutzer einen Wert aus der Combobox Liste ausgewählt hat

Beitrag von fliegermichl »

@wp_xyz
Das scheint mir tatsächlich der sinnvollste Weg zu sein.

Benutzeravatar
Winni
Beiträge: 503
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.06, fpc 3.04
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Reagieren darauf das ein Benutzer einen Wert aus der Combobox Liste ausgewählt hat

Beitrag von Winni »

Hi!

Kann man alles abfangen in KeyDown. Und weiterleiten.
Auch ESC oder Funktionstasten.

Deine Lösung ist echt was für Mausschubser oder 1-Finger-Akkrobaten.

Meine 10-Finger-Kollegen würden reichlich meckern, wenn ich ihnen so etws anbieten würde.
Zu recht.
Die sehen übrigens weder auf den Bildschirm noch auf die Tastatur wenn sie tippen.
Die sehen auf das papierne Dokument, das sie bearbeiten.
Im Vorlagenhalter auf Augenhöhe.

Winni

Antworten