Chcę zaakceptować cyfry i kropkę dziesiętną, ale bez znaku.
Patrzyłem na próbki przy użyciu kontrolki NumericUpDown dla formularzy Windows Forms i tej próbki niestandardowej kontrolki NumericUpDown firmy Microsoft . Ale do tej pory wydaje się, że NumericUpDown (obsługiwany przez WPF lub nie) nie zapewni funkcjonalności, której chcę. Sposób, w jaki zaprojektowano moją aplikację, nikt przy zdrowych zmysłach nie będzie chciał zadzierać ze strzałkami. W kontekście mojej aplikacji nie mają one praktycznego sensu.
Szukam więc prostego sposobu, aby standardowy WPF TextBox akceptował tylko te znaki, które chcę. czy to możliwe? Czy to jest praktyczne?
double.TryParse()
prawdopodobnie zostałoby zaimplementowane z taką samą liczbą linii i byłoby bardziej elastyczne.Moduł obsługi zdarzeń wyświetla podgląd tekstu. W tym przypadku wyrażenie regularne pasuje do wpisywanego tekstu tylko wtedy, gdy nie jest liczbą, a następnie nie jest wprowadzane do pola tekstowego wprowadzania.
Jeśli chcesz tylko litery, zamień wyrażenie regularne na
[^a-zA-Z]
.XAML
PLIK XAML.CS
źródło
Wykorzystałem część tego, co już tu było i nadałem temu swój własny styl, dzięki czemu nie muszę propagować tego kodu w całej masie wyświetleń ...
Oto odpowiedni kod widoku:
źródło
To ulepszone rozwiązanie odpowiedzi WilP . Moje ulepszenia to:
EmptyValue
właściwość, jeśli pusty ciąg jest nieodpowiedniUżycie jest dość proste:
źródło
MaxLength
ustawisz warunku,(this.MaxLength == 0 || text.Length <= this.MaxLength)
zawsze wracafalse
podczas testowania nowego tekstu. Powinno to być lepsze,(this.MaxLength == int.MinValue || text.Length <= this.MaxLength)
ponieważ ustawiłeśint.MinValue
wartość domyślną dlaMaxLength
.UpdateSourceTrigger=PropertyChanged
do wiązania. Masz pomysł, jak uruchomić ten kod, gdy zmienisz goUpdateSourceTrigger
naPropertyChanged
? Dziękujemy za udostępnienie tego kodu.Oto bardzo prosty i łatwy sposób, aby to zrobić za pomocą MVVM.
Powiąż swój textBox z wartością całkowitą w modelu widoku, a to będzie działać jak klejnot ... wyświetli nawet sprawdzenie poprawności, gdy w polu tekstowym zostanie wprowadzona liczba całkowita.
Kod XAML:
Wyświetl kod modelu:
źródło
long
nafloat
, ale nie działało to dobrze z natychmiastową weryfikacją. DodałemUpdateSourceTrigger="PropertyChanged"
do powiązania, aby sprawdzanie poprawności odbywało się, gdy każdy znak był wpisywany, i nie mógł już wpisać „.” w TextBox, chyba że pojawił się niedozwolony znak (musiał wpisać „1x.234”, a następnie usunąć „x”). W tym trybie wydaje się też nieco powolny. Wydaje się, że jest to przydatneSystem.Number.ParseSingle()
do wykonywania pracy, więc akceptuje różne notacje.Dodaj ZASADĘ WALIDACJI, aby przy zmianie tekstu sprawdzić, czy dane są liczbowe, a jeśli tak, pozwala na kontynuowanie przetwarzania, a jeśli nie, monituje użytkownika, że w tym polu akceptowane są tylko dane liczbowe.
Przeczytaj więcej w Sprawdzanie poprawności w Windows Presentation Foundation
źródło
double
który już zapewnia standardową weryfikację.Rozszerzony zestaw narzędzi WPF ma jeden: NumericUpDown
źródło
NumericUpDown
jest już przestarzały. możesz skorzystaćDecimalUpDown
ze zaktualizowanego zestawu narzędzi RozszerzonaMożna również po prostu zaimplementować regułę sprawdzania poprawności i zastosować ją do TextBox:
Po wdrożeniu reguły w następujący sposób (przy użyciu tego samego Regex, co zaproponowano w innych odpowiedziach):
źródło
Tutaj mam proste rozwiązanie zainspirowane odpowiedzią Raya . Powinno to wystarczyć do zidentyfikowania dowolnej liczby.
To rozwiązanie można również łatwo zmodyfikować, jeśli chcesz mieć tylko liczby dodatnie, wartości całkowite lub wartości dokładne do maksymalnej liczby miejsc po przecinku itp.
Jak sugeruje odpowiedź Raya , musisz najpierw dodać
PreviewTextInput
wydarzenie:Następnie wstaw następujący kod do kodu:
źródło
Dopuszczałem numery klawiatury numerycznej i backspace:
źródło
var keyEnum = (System.Windows.Input.Key) e.Key; e.Handled = !(keyEnum >= System.Windows.Input.Key.D0 && keyEnum <= System.Windows.Input.Key.D9 || keyEnum >= System.Windows.Input.Key.NumPad0 && keyEnum <= System.Windows.Input.Key.NumPad9 || keyEnum == System.Windows.Input.Key.Back);
Zakładam, że:
W TextBox, dla którego chcesz zezwalać na wprowadzanie numeryczne, właściwość Text początkowo jest ustawiona na pewną prawidłową wartość liczbową (na przykład 2.7172).
Twoje pole tekstowe jest dzieckiem twojego głównego okna
Twoje główne okno należy do klasy Window1
Twoja nazwa TextBox to numeryczna TB
Podstawowy pomysł:
Dodaj:
private string previousText;
do głównej klasy okna (Window1)Dodaj:
previousText = numericTB.Text;
do głównego konstruktora oknaUtwórz moduł obsługi zdarzenia numericTB.TextChanged, aby wyglądał mniej więcej tak:
Spowoduje to ustawianie previousText na numericTB.Text tak długo, jak będzie to ważne, i ustawi numericTB.Text na ostatnią prawidłową wartość, jeśli użytkownik napisze coś, co ci się nie podoba. Oczywiście jest to tylko podstawowy pomysł i jest on „idiotoodporny”, a nie „idiotyczny”. Na przykład nie obsługuje przypadku, w którym użytkownik miesza spacje. Oto kompletne rozwiązanie, które moim zdaniem jest „idiotyczne”, a jeśli się mylę, proszę mi powiedzieć:
Zawartość pliku Window1.xaml:
Zawartość pliku Window.xaml.cs:
I to wszystko. Jeśli masz wiele TextBoxów, polecam utworzenie CustomControl, który dziedziczy z TextBox, abyś mógł zawinąć previousText i numericTB_TextChanged w osobny plik.
źródło
Jest to jedyny potrzebny kod:
Umożliwia to wprowadzanie liczb tylko w polu tekstowym.
Aby umożliwić znak dziesiętny lub znak minus, możesz zmienić wyrażenie regularne na
[^0-9.-]+
.źródło
Jeśli nie chcesz pisać dużo kodu, aby wykonać podstawową funkcję (nie wiem, dlaczego ludzie robią długie metody), możesz po prostu to zrobić:
Dodaj przestrzeń nazw:
W XAML ustaw właściwość TextChanged:
W WPF w metodzie txt1_TextChanged dodaj
Regex.Replace
:źródło
Innym podejściem będzie użycie załączonego zachowania, zaimplementowałem mój niestandardowy TextBoxHelper klasę , której można używać w w całym projekcie. Ponieważ pomyślałem, że subskrybowanie wydarzeń dla każdego pola tekstowego i każdego pliku XAML w tym celu może być czasochłonne.
Zaimplementowana klasa TextBoxHelper ma następujące funkcje:
Oto implementacja klasy TextBoxHelper:
A oto przykład jego łatwego użycia:
Lub
Zauważ, że mój TextBoxHelper znajduje się w aliasie viewHelpers xmlns.
Mam nadzieję, że ta implementacja ułatwia pracę innym :)
źródło
w podglądzie zdarzenie keydown pola tekstowego.
źródło
źródło
.
, ponieważe.Text
zwraca tylko ostatni wprowadzony znak, a kropka nie powiedzie się podczasIsDigit
sprawdzania.Dla tych, którzy szukają szybkiej i bardzo prostej implementacji tego typu problemu, używając tylko liczb całkowitych i dziesiętnych, w pliku XAML dodaj
PreviewTextInput
właściwość do pliku,TextBox
a następnie do pliku xaml.cs:Nadmiarowe jest sprawdzanie całego łańcucha za każdym razem, chyba że, jak wspomnieli inni, robisz coś z notacją naukową (aczkolwiek, jeśli dodajesz pewne znaki, takie jak „e”, proste wyrażenie regularne dodające symbole / znaki to bardzo proste i zilustrowane w innych odpowiedziach). Ale dla prostych wartości zmiennoprzecinkowych to rozwiązanie wystarczy.
Napisane jako jednowarstwowe z wyrażeniem lambda:
źródło
Możemy przeprowadzić weryfikację zdarzenia zmienionego w polu tekstowym. Poniższa implementacja uniemożliwia wprowadzanie naciśnięć klawiszy innych niż numeryczne i jeden przecinek dziesiętny.
źródło
Co powiesz na to? Działa dla mnie dobrze. Mam nadzieję, że nie przegapiłem żadnych skrzyń ...
źródło
W Windows Forms było to łatwe; możesz dodać wydarzenie do KeyPress i wszystko działa łatwo. Jednak w WPF tego zdarzenia nie ma. Ale jest na to znacznie łatwiejszy sposób.
WPF TextBox ma zdarzenie TextChanged, które jest ogólne dla wszystkiego. Obejmuje to wklejanie, pisanie na klawiaturze i wszystko, co może przyjść ci do głowy.
Możesz więc zrobić coś takiego:
XAML:
KOD ZA:
Akceptuje to również
.
, jeśli nie chcesz, po prostu usuń go zregex
instrukcji@[^\d]
.Uwaga : To zdarzenie może być użyte na wielu obiektach TextBox, ponieważ wykorzystuje ono
sender
tekst obiektu. Zapisujesz zdarzenie tylko raz i możesz go użyć dla wielu TextBoxów.źródło
Teraz wiem, że to pytanie ma zaakceptowaną odpowiedź , ale osobiście uważam, że jest to trochę mylące i uważam, że powinno być łatwiejsze. Spróbuję więc wykazać, w jaki sposób sprawiłem, by działał jak najlepiej:
W Windows Forms istnieje zdarzenie o nazwie
KeyPress
doskonale nadające się do tego rodzaju zadania. Ale to nie istnieje w WPF , więc zamiast tego będziemy używaćPreviewTextInput
zdarzenia. Ponadto do walidacji uważam, że można użyćforeach
pętli dotextbox.Text
sprawdzenia i sprawdzenia, czy pasuje ;) warunek, ale szczerze mówiąc, to właśnie wyrażenia regularne służą .Jeszcze jedna rzecz, zanim zanurzymy się w świętym kodeksie . Aby zdarzenie zostało odpalone, można zrobić dwie rzeczy:
<PreviewTextInput="textBox_PreviewTextInput/>
Loaded
przypadku formularza (w którym znajduje się textBox):textBox.PreviewTextInput += onlyNumeric;
Myślę, że druga metoda jest lepsza, ponieważ w sytuacjach takich jak ten, najczęściej będziesz musiał zastosować ten sam warunek (
regex
) do więcej niż jednegoTextBox
i nie chcesz się powtarzać! .Wreszcie, oto jak to zrobić:
źródło
Oto moja wersja. Opiera się na
ValidatingTextBox
klasie bazowej, która po prostu cofa to, co zostało zrobione, jeśli nie jest „prawidłowe”. Obsługuje wklejanie, wycinanie, usuwanie, cofanie, +, - itp.Dla 32-bitowej liczby całkowitej istnieje klasa Int32TextBox, która po prostu porównuje się z liczbą całkowitą. Dodałem także klasy sprawdzania zmiennoprzecinkowego.
Uwaga 1: Używając powiązania WPF, musisz upewnić się, że używasz klasy, która pasuje do powiązanego typu właściwości, w przeciwnym razie może to prowadzić do dziwnych wyników.
Uwaga 2: Jeśli używasz klas zmiennoprzecinkowych z powiązaniem WPF, upewnij się, że powiązanie używa bieżącej kultury w celu dopasowania metody TryParse, której użyłem.
źródło
Oto biblioteka do wprowadzania numerycznego w WPF
Ma właściwości takie jak
NumberStyles
iRegexPattern
do sprawdzania poprawności.Podklasy WPF
TextBox
źródło
Posługiwać się:
źródło
Pracowałem z niezwiązanym pudełkiem dla prostego projektu, nad którym pracowałem, więc nie mogłem zastosować standardowego podejścia do wiązania. W związku z tym stworzyłem prosty hack, który inni mogą uznać za przydatny, po prostu rozszerzając istniejącą kontrolę TextBox:
Oczywiście dla typu zmiennoprzecinkowego chciałbyś go parsować jako zmiennoprzecinkowe i tak dalej. Obowiązują te same zasady.
Następnie w pliku XAML musisz dołączyć odpowiednią przestrzeń nazw:
Następnie możesz używać go jako zwykłej kontroli:
źródło
Po pewnym czasie korzystania z niektórych tutaj rozwiązań, opracowałem własny, który działa dobrze dla mojej konfiguracji MVVM. Zauważ, że nie jest tak dynamiczny jak niektóre inne w tym sensie, że wciąż pozwala użytkownikom wprowadzać błędne znaki, ale blokuje im to możliwość naciśnięcia przycisku i zrobienia czegokolwiek. Jest to zgodne z moim motywem wyszarzania przycisków, gdy nie można wykonać akcji.
Mam,
TextBox
że użytkownik musi wprowadzić wiele stron dokumentu do wydrukowania:... z tą właściwością wiązania:
Mam też przycisk:
... z tym wiązaniem polecenia:
Jest też metoda
SetNumberOfPages()
, ale nie ma znaczenia dla tego tematu. Działa dobrze w moim przypadku, ponieważ nie muszę dodawać żadnego kodu do pliku za kodem widoku i pozwala mi kontrolować zachowanie za pomocąCommand
właściwości.źródło
Podczas sprawdzania wartości liczbowej można użyć funkcji VisualBasic.IsNumeric .
źródło
W aplikacji WPF możesz sobie z tym poradzić, obsługując
TextChanged
zdarzenie:źródło
Dla programistów, którzy chcą, aby ich pola tekstowe akceptowały tylko niepodpisane liczby, takie jak porty gniazd itp.:
WPF
DO#
źródło
65535
. Jeśli jest większy, to nie jest prawidłowy port. Również ustawienieTextBox.MaxLength
TO5
pomogłoby albo programowo lub w XAML .Oto, czego użyłbym, aby uzyskać pole tekstowe WPF, które akceptuje cyfry i kropkę dziesiętną:
Umieść kod w nowym pliku klasy, dodaj
u góry pliku i skompiluj rozwiązanie. Kontrolka numericTextBox pojawi się na górze przybornika.
źródło