Numerische TextBox - Double.TryParse
Ich weiß, das ist eine uralte Frage mit vielen Antworten, aber ich habe nicht gefunden eine gute, robuste Antworten.
Voraussetzung ist eine textbox, wird immer eine Zeichenfolge enthalten, die Doppel.TryParse wird true zurückgegeben.
Meisten Implementierungen, die ich gesehen habe nicht Schutz gegen Eingabe wie: "10.45.8". Das ist ein problem.
Die bevorzugte Art und Weise, dies zu tun, ist durchaus mit Veranstaltungen wie TextInput und KeyDown (für Leerzeichen). Das problem mit diesen ist, dass es ziemlich kompliziert, um ein string, der den neuen Text ein, bevor es geändert wird (oder der alte Text, nachdem es geändert wird). Das problem mit TextChanged ist, dass es nicht bieten einen Weg, um den alten Text.
Wenn Sie könnte irgendwie bekommt der neue Text, bevor Sie es verpasst, wäre das sehr hilfreich, da könnte man es testen gegen Verdoppeln.TryParse. Möglicherweise gibt es eine bessere Lösung, obwohl.
Was ist der beste Weg, dies zu tun?
Die beste Antwort auf diese Frage ist eine, die hat mehrere Ansätze und vergleicht diese.
Was macht Sie sagen, dass? Ist das nicht einfach genug Bedarf?
was soll passieren, wenn der Benutzer eine ungültige char dann lässt die textbox?
Wenn Sie geben Sie eine ungültige char, sollte es nichts zu tun, wie Sie nicht drücken Sie die Taste.
Ich würde versuchen, dass die Anforderung abgeworfen für usability-Gründen - siehe meine Antwort.
InformationsquelleAutor Kendall Frey | 2012-02-03
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ansatz 1
Verwenden Sie eine Kombination der
TextChanged
undKeyDown
Veranstaltungen für eineTextBox
. AufKeyDown
speichern Sie den aktuellen text in das Textfeld, und geben Sie dann IhrDouble.TryParse
imTextChanged
Veranstaltung. Wenn Sie den text eingegeben haben ist nicht gültig, dann würden Sie wieder den alten text Wert. Dies würde wie folgt Aussehen:Den
CaratIndex
ist nützlich, nicht störend für den Benutzer, den Tod mit bewegen Sie den cursor auf die erste position, auf die die überprüfung nicht bestanden. Jedoch, diese Methode nicht zu fangen die Leertaste drücken. Es wird zulassen, die text eingegeben werden, wie dieses "1234.56 ". Auch das einfügen von text werden nicht ordnungsgemäß überprüft. Darüber hinaus weiß ich nicht wie messing mit dem event-Handler im text aktualisieren.Ansatz 2
Dieser Ansatz sollte Ihren Bedürfnissen entsprechen.
Verwenden Sie die
PreviewKeyDown
undPreviewTextInput
event-Handler. Durch die Beobachtung dieser Ereignisse und Handhabung entsprechend, die Sie nicht brauchen, um über das zurücksetzen auf eine Vorherige text Wert in das Textfeld.PreviewKeyDown
können verwendet werden, um für die Uhr und ignorieren Sie Ihre Leertaste drücken undPreviewTextInput
können verwendet werden, um zu testen, Ihre neue textbox Wert, bevor es zugewiesen wird.Dieser Ansatz macht einen besseren job zu fangen ungültige Eingabe, bevor es in die textbox. Jedoch, die Einstellung der Ereignis
Handled
ich nehme an, könnten Sie in Schwierigkeiten geraten, je nach den rest der Destinationen in der routing-Liste für die Nachricht. Ein letztes Stück, das nicht hier behandelt wird, ist die Fähigkeit der Benutzer das einfügen Ungültiger Eingabe in das Textfeld. Dies kann umgegangen werden mit dem Zusatz von diesem code, der aufgebaut ist aus der Paste-Ereignis in eine WPF TextBox.Fügen Sie diese Prozedur mit diesem code nach der
InitializeComponent
nennen:Frage zu Ansatz 1: PreviewTextInput besser funktionieren würde als KeyDown, richtig? (Es ist Geräte-unabhängig. Und mein Szenario geschieht, zu sein auf einem tablet, wo ein Benutzer möglicherweise nicht eine Tastatur verwenden.)
Wenn KeyDown oder PreviewKeyDown nicht funktionieren wird auf Ihrem Gerät der Fall, müssen Sie behandeln wird, wie man die Space-Taste drücken, ich glaube nicht, das Feuer, die PreviewTextInput Veranstaltung.
Es gibt mehr Probleme als nur die Leertaste, siehe meine Antwort (und das ist abgesehen von diesem Raum ist eine gültige Trennzeichen für Tausender in einigen Kulturen, wie z.B. fr-FR).
InformationsquelleAutor Adam S
Es ist wirklich ärgerlich, dass
TextBox
nichtPreviewTextChanged
Ereignis und jeder sollte die erfinden das Rad jedes mal zu emulieren. Ich löste genau das gleiche Problem vor kurzem und veröffentlichte sogar meine Lösung auf github als WpfEx Projekt (werfen Sie einen Blick auf TextBoxBehavior.cs und TextBoxDoubleValidator.cs).Adam S Antwort ist sehr gut, aber wir sollten überlegen, einige andere Ecke Fälle als gut.
Während coputing resultierende text in unserer
textBox_PreviewTextInput
event-handler sollten wir Bedenken, dass Benutzer können wählen Sie etwas text in der text-box und neue Eingabe ersetzen. Wir sollten also so etwas wie:Und wir sollten mit der gleichen Logik, wenn wir damit umgehen, OnPaste event.
Wir können nicht einfach Verdoppeln.TryParse, weil Benutzer kann den Typ '+.' zu geben '+.1' ('+.1' - ist absolut gültigen string für double), so dass unsere Validierung der Methode sollte true zurückgeben, auf '+.' oder' -. ' - Saiten (ich selbst erstellt separate Klasse namens
TextBoxDoubleValidator
und das einstellen der unit-tests, weil diese Logik ist so wichtig).Bevor Sie Graben sich in die Implementierung schauen wir uns die Reihe von unit-tests, der für alle corner cases für die Validierung der Methode:
Hinweis, dass ich mit SetCulture("en-US") - Attribut, weil Dezimaltrennzeichen "lokale-spezifische".
Ich denke, ich Decke alle Ecke Fälle mit den tests, aber mit diesem Werkzeug in Ihren Händen können Sie ganz einfach "emulieren" user-imput und überprüfen (und Wiederverwendung) Fällen, was Sie wollen. Und nun werfen wir einen Blick auf
TextBoxDoubleValidator.IsValid
Methode:Beispiel sind fehlende Klassen/extensions so seine 1 als nicht brauchbar out of the box
InformationsquelleAutor Sergey Teplyakov
Einen Kommentar statt einer Antwort, aber...
Ich würde mich hüten Sie sich vor der Validierung der Eingabe auf jeden Tastendruck wie kann es unerwünschte Folgen haben und ärgern den Anwender.
Zum Beispiel, ich erinnere mich geärgert, indem ein datepicker-Steuerelement, die nicht erlauben würde, Daten in der Zukunft, und initialisiert wurde, auf das heutige Datum. Es erfolgt die Validierung nach der Eingabe von Tag, Monat oder Jahr, so dass es unmöglich war, zu geben Sie Monat/Tag später als das aktuelle Datum ohne die erste änderung des Jahres.
In die Doppel, Sie hätte ein ähnliches problem, zum Beispiel die von Ihnen vorgeschlagene Validierung würde verhindern, dass der Benutzer von der Eingabe des absolut gültigen Werte "-1", ".12", "1e+5":
Ich würde empfehlen, die Validierung als normal, wenn der Benutzer verlässt die textbox oder explizit überprüft, indem Sie auf eine Schaltfläche.
InformationsquelleAutor Joe