Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi NumbersOnly bei TDateTimePicker (https://www.delphipraxis.net/199434-numbersonly-bei-tdatetimepicker.html)

JanTera 23. Jan 2019 10:55

Delphi-Version: XE8

NumbersOnly bei TDateTimePicker
 
Hallo

Ich muss den Standardkomponent "TDateTimePicker" verwenden, doch leider habe ich das Problem, dass man auch Buchstaben und Zeichen, anstatt nur Zahlen eingeben kann. Wenn man kein akzeptables Datumformat benutzt (oder eben z.B. Buchstaben), stürzt mein Programm ab.
Ich habe auch versucht, die Exception abzufangen, aber der Fehler wird immer schon vor meinem Abfangversuch geworfen.

Ich suche entweder nach einer Property die sagt, dass man nur Zahlen angeben kann, oder einen Weg, die Exception früh genug abzufangen.

Danke

Uwe Raabe 23. Jan 2019 11:08

AW: NumbersOnly bei TDateTimePicker
 
Gibt es ein Beispielprogramm, mit dem man das Problem nachvollziehen kann?

EWeiss 23. Jan 2019 11:11

AW: NumbersOnly bei TDateTimePicker
 
Delphi-Quellcode:
function IsNumeric(const s: string): Boolean;
const
  NUMBERS = ['0'..'9'];
var
  i: integer;
begin
  Result := true;

  for i := 1 to Length(s) do
  if not (CharInSet(s[i], NUMBERS)) then
    begin
      Result := false;
      Exit;
  end;

end;
gruss

JanTera 23. Jan 2019 11:26

AW: NumbersOnly bei TDateTimePicker
 
@Uwe
Für was brauchst du ein Beispielprogramm? Wenn man bei einem TDateTimePicker einen Buchstaben eingibt und Enter drückt, gibt es eine Exception. Wie ich das verhindere, war die Frage.

@EWeiss
Danke für die Antwort, aber herauszufinden, ob ein Zeichen eine Zahl ist oder nicht war nicht das Problem. Das Problem ist, dass die Exception zu früh geworfen wird und ich sie nicht abfangen kann.

Danke für die Antworten

philipp.hofmann 23. Jan 2019 11:32

AW: NumbersOnly bei TDateTimePicker
 
und es einfach in KeyDown abfangen?

Delphi-Quellcode:
procedure TicTrainerF.cbLegRatioKeyDown(Sender: TObject; var Key: Word; var KeyChar: Char; Shift: TShiftState);
begin
  if (pos(keyChar,'0123456789')<=0) then
  begin
    keyChar:=#0;
    exit;
  end;
end;

taveuni 23. Jan 2019 12:16

AW: NumbersOnly bei TDateTimePicker
 
Oder einfach diese Spezifische Exception selbst abfangen (behandeln)?

haentschman 23. Jan 2019 12:25

AW: NumbersOnly bei TDateTimePicker
 
Oder einfach...den User nicht das Datum manuell eingeben lassen. Aus Erfahrung erleichert das das Handling. :wink: Den DateTimePicker.Date sinnvoll vorzubelegen ist natürlich Voraussetzung.

Delphi.Narium 23. Jan 2019 12:27

AW: NumbersOnly bei TDateTimePicker
 
Im Ereignis OnUserInput den Eingabestring prüfen und die Änderung nur erlauben, wenn ein gültiges Datum vorliegt.

PS.:

Mir gelingt es nicht bei meiner Delphiversion beim TDateTimePicker was anderes als Ziffern einzugeben. Buchstaben, Sonderzeichen ... werden nicht angenommen und führen zu keinerlei Reaktion seitens der Komponente.

Daher bitte Quelltext und kompilierte Version hier anhängen, so dass man das prüfen kann, eventuell liegt ein Fehler vor, der nur die von Dir genutzte Delphiversion betrifft.

JanTera 23. Jan 2019 12:32

AW: NumbersOnly bei TDateTimePicker
 
Danke an Delphi.Narium für die erste hilfreiche Antwort.

Ich kann leider die Kompilierte Version nicht einfach so anhängen, da sie 1. viel zu gross ist und 2. nicht open-source ist.

Ich nehme an, du kannst nur Ziffern eingeben, da du die Eigenschaft ParseInput nicht auf true hast. Leider muss in meinem Fall ParseInput an sein.

Das mit onUserInput werde ich versuchen.

Danke!

PS: Ich benutze delphi XE8

H.Bothur 23. Jan 2019 12:38

AW: NumbersOnly bei TDateTimePicker
 
Zitat:

Zitat von JanTera (Beitrag 1423962)
Danke an Delphi.Narium für die erste hilfreiche Antwort.

Hilfreich waren auch die anderen Antworten - übrigens auch wenn Du nicht den ganzen Source hier reinstellen kannst dann wärees geschickt gewesen ein Miniprogramm zu erstellen bei genau dieser Fehler vorkommt. Du wirst wohl nicht von den anderen ier Anwesenden erwarten das die das alle bei sich nachstellen, oder ?

Gruß
Hans

Moombas 23. Jan 2019 13:11

AW: NumbersOnly bei TDateTimePicker
 
Zitat:

Zitat von JanTera (Beitrag 1423962)
Ich nehme an, du kannst nur Ziffern eingeben, da du die Eigenschaft ParseInput nicht auf true hast. Leider muss in meinem Fall ParseInput an sein.

PS: Ich benutze delphi XE8

In Delphi 10.2 kannst du auch mit aktiviertem Parse nur Zahlen eingeben, eben getestet.

JanTera 23. Jan 2019 13:12

AW: NumbersOnly bei TDateTimePicker
 
@h.bothur
Sie waren eben nicht besonders hilfreich. Aber ich habe auch nicht gut erklärt was mein Problem ist, also ist es eher meine Schuld

Ich erwarte auf jeden Fall nicht, dass das jeder hier bei sich nachstellt. Auch wenn es nicht lange dauern würde (man muss nur ein TDateTimePicker auf eine Form ziehen und ParseInput aktivieren).

Moombas 23. Jan 2019 13:33

AW: NumbersOnly bei TDateTimePicker
 
Zitat:

Zitat von JanTera (Beitrag 1423967)
@h.bothur
Sie waren eben nicht besonders hilfreich. Aber ich habe auch nicht gut erklärt was mein Problem ist, also ist es eher meine Schuld

Ich erwarte auf jeden Fall nicht, dass das jeder hier bei sich nachstellt. Auch wenn es nicht lange dauern würde (man muss nur ein TDateTimePicker auf eine Form ziehen und ParseInput aktivieren).

Jeder der dir helfen möchte, wird es ggf. bei sich eben kurz nachstellen. Das ist zur Fehlerfindung auch ggf. notwendig. Aktuell sieht es so aus, das der Fehler bei dir woanders herrührt oder der Fehler nur in der Delphi Version die du nutzt vorhanden ist.
Um das zu prüfen, müsstest du eben genau das machen was du beschrieben hast:

Eine Form erstellen, TDateTimePicker rauf schieben, Programm starten und versuchen Buchstaben etc. einzugeben. Ergebnis zur weiteren Fehlersuche nutzen. Ein schnelleres Ergebnis kannst du nicht haben.

Delphi.Narium 23. Jan 2019 13:43

AW: NumbersOnly bei TDateTimePicker
 
Wenn man ParseInput auf True stellt, wird das Ereignis onUserInput aufgerufen. Mir scheint in diesem Zusammenhang zwingend, dieses Ereignis auch auszuwerten und die Eingabe auf Gültigkeit zu prüfen. Man sagt durch ParseInput = True quasi: "Lieber DateTimePicker, kümmere Dich nicht um die Eingabe, das mach' ich selber."

Allerdings bekomme ich auch hier (ohne das Ereignis OnUserInput zu verarbeiten) beim Verlassen des TDateTimePickers, ohne gültige Eingabe, eine sinnvolle Fehlermeldung.

Es könnte sein, dass die Attribute Format und Kind (eventuell auch noch weitere) da irgendwie mit hineinspielen.

JanTera 23. Jan 2019 13:54

AW: NumbersOnly bei TDateTimePicker
 
ja.

Uwe Raabe 23. Jan 2019 13:55

AW: NumbersOnly bei TDateTimePicker
 
Zitat:

Zitat von JanTera (Beitrag 1423967)
(man muss nur ein TDateTimePicker auf eine Form ziehen und ParseInput aktivieren).

Genau das genügt ja offenbar nicht allein, um das Problem nachzuvollziehen.

Wenn es denn so einfach ist, ein Testprogramm zu erstellen, warum schaffst du es dann nach nunmehr 15 Posts immer noch nicht?

Schokohase 24. Jan 2019 07:49

AW: NumbersOnly bei TDateTimePicker
 
Da der TE es nicht schafft (oder eher nicht will) einen Source zu liefern um das nachzustellen, hier ist es:
Delphi-Quellcode:
type
  TMainForm = class(TForm)
    ApplicationEvents1: TApplicationEvents;
    DateTimePicker1: TDateTimePicker;
    ListBox1: TListBox;
    procedure ApplicationEvents1_Exception(Sender: TObject; E: Exception);
    procedure DateTimePicker1_UserInput(Sender: TObject; const UserString: string; var DateAndTime: TDateTime; var AllowChange: Boolean);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
    constructor Create(AOwner: TComponent); override;

  end;

var
  MainForm: TMainForm;

implementation

{$R *.dfm}

procedure TMainForm.ApplicationEvents1_Exception(Sender: TObject; E: Exception);
begin
  // TODO -cMM: TMainForm.ApplicationEvents1_Exception default body inserted
  ListBox1.Items.Add(E.ClassName + ': ' + E.Message);
end;

constructor TMainForm.Create(AOwner: TComponent);
begin
  inherited;
  ApplicationEvents1.OnException := ApplicationEvents1_Exception;

  DateTimePicker1.AlignWithMargins := True;
  DateTimePicker1.Align := alTop;
  DateTimePicker1.ParseInput := True;
  DateTimePicker1.OnUserInput := DateTimePicker1_UserInput;

  ListBox1.AlignWithMargins := True;
  ListBox1.Align := alClient;
end;

procedure TMainForm.DateTimePicker1_UserInput(Sender: TObject; const UserString: string; var DateAndTime: TDateTime; var AllowChange: Boolean);
begin
  // TODO -cMM: TMainForm.DateTimePicker1_UserInput default body inserted
  ListBox1.Items.Add('DateTimePicker1_UserInput ' + UserString);
end;
Folgende Vorgehensweise führt bei Delphi 10.3 zu einem
Delphi-Quellcode:
EConvertError
:
  • Mit der linken Maus-Taste rechts neben dem Datum in den Picker klicken
  • Jetzt sollte das ganze Datum markiert sein
  • Über die Tastatur den Text
    Delphi-Quellcode:
    morgen
    eintippen
  • Die Enter-Taste drücken
Wie man sieht, sieht man, dass die
Delphi-Quellcode:
DateTimePicker1_UserInput
Methode nicht aufgerufen wird, aber dafür gibt es den
Delphi-Quellcode:
EConvertError
Code:
EConvertError: 'morgen' ist keine gültige Datums- und Uhrzeitangabe
UPDATE

Und zwei Klicks weiter im Debugger hat man auch schon den Übeltäter lokalisiert:
Vcl.ComCtrls - Zeile 28152
Delphi-Quellcode:
      DTN_USERSTRINGA, DTN_USERSTRINGW:
        begin
          DateTimeString := NMDateTimeString;
          with DateTimeString{$IFNDEF CLR}^{$ENDIF} do
          begin
{$IFDEF CLR}
            UserString := Marshal.PtrToStringAuto(pszUserString);
{$ELSE}
            UserString := pszUserString;
{$ENDIF}
            DT := StrToDateTime(UserString); // das ist der Übeltäter
            if Assigned(FOnUserInput) then
            begin
              AllowChange := True;
              FOnUserInput(Self, UserString, DT, AllowChange);
              dwFlags := Ord(not AllowChange);
            end
            else
              dwFlags := Ord(False);
            DateTimeToSystemTime(DT, st);
          end;

Bevor man die Chance bekommt den Eingabestring zu verarbeiten wird dieser schon von der Komponente geparst und es kommt zur Exception.

Könnte sich um einen Bug handeln. Dazu müsste man dieses Verhalten mit der Dokumentation abgleichen, was die Komponente denn so machen sollte.

Uwe Raabe 24. Jan 2019 08:04

AW: NumbersOnly bei TDateTimePicker
 
Zitat:

Zitat von Schokohase (Beitrag 1424012)
Da der TE es nicht schafft (oder eher nicht will) einen Source zu liefern um das nachzustellen, hier ist es:

Geht doch :thumb:

Dennis07 25. Jan 2019 04:17

AW: NumbersOnly bei TDateTimePicker
 
Sowas würde ich aber niemals in KeyDown oder KeyPress packen, weil es nicht auf andere Messages (wie zB. Paste) reagiert. Besser wäre es, dies ins Change-Event zu packen. Noch besser wäre es aber, das UserInput-Ereignis zu nehmen (wurde ja schon erklärt).


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