410 Stimmen

Wie bekomme ich eine TextBox nur numerische Eingabe in WPF zu akzeptieren?

Ich möchte Ziffern und das Dezimalkomma akzeptieren, aber kein Vorzeichen.

Ich habe mir Beispiele angesehen, die das NumericUpDown-Steuerelement für Windows Forms verwenden, und dieses Beispiel für ein benutzerdefiniertes Steuerelement NumericUpDown von Microsoft . Aber bisher scheint es wie NumericUpDown (unterstützt von WPF oder nicht) ist nicht gehen, um die Funktionalität, die ich will zu bieten. Die Art und Weise meine Anwendung entworfen ist, niemand bei klarem Verstand wird wollen, um mit den Pfeilen zu verwirren. Sie machen keinen praktischen Sinn, im Kontext meiner Anwendung.

Also ich bin auf der Suche nach einem einfachen Weg, um eine Standard-WPF-TextBox akzeptieren nur die Zeichen, die ich will. Ist dies möglich? Ist es praktisch?

8voto

Hamzeh Soboh Punkte 7354

Ich habe die Zifferntastatur und die Rücktaste zugelassen:

    private void TextBox_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        int key = (int)e.Key;

        e.Handled = !(key >= 34 && key <= 43 || 
                      key >= 74 && key <= 83 || 
                      key == 2);
    }

6voto

Everyone Punkte 1623

In Windows Forms war es einfach; Sie können ein Ereignis für KeyPress hinzufügen und alles funktioniert problemlos. In WPF ist dieses Ereignis jedoch nicht vorhanden. Aber es gibt einen viel einfacheren Weg für sie.

Die WPF-Textbox hat das Ereignis TextChanged, das für alles gilt. Es umfasst das Einfügen, Tippen und alles, was Ihnen in den Sinn kommen kann.

Sie können also etwa so vorgehen:

XAML:

<TextBox name="txtBox1" ... TextChanged="TextBox_TextChanged"/>

CODE BEHIND:

private void TextBox_TextChanged(object sender, TextChangedEventArgs e) {
    string s = Regex.Replace(((TextBox)sender).Text, @"[^\d.]", "");
    ((TextBox)sender).Text = s;
}

Dies gilt auch für . Wenn Sie das nicht wollen, entfernen Sie es einfach aus dem regex Anweisung zu sein @[^\d] .

Hinweis : Dieses Ereignis kann für viele TextBoxen verwendet werden, da es die sender Text des Objekts. Sie schreiben das Ereignis nur einmal und können es für mehrere TextBoxen verwenden.

6voto

iato Punkte 357

Wenn Sie nicht viel Code für eine einfache Funktion schreiben wollen (ich weiß nicht, warum die Leute lange Methoden machen), können Sie dies einfach tun:

  1. Namespace hinzufügen:

    using System.Text.RegularExpressions;
  2. Legen Sie in XAML eine TextChanged-Eigenschaft fest:

    <TextBox x:Name="txt1" TextChanged="txt1_TextChanged"/>
  3. In WPF unter txt1_TextChanged Methode, hinzufügen Regex.Replace :

    private void txt1_TextChanged(object sender, TextChangedEventArgs e)
    {
        txt1.Text = Regex.Replace(txt1.Text, "[^0-9]+", "");
    }

6voto

user666535 Punkte 69

Davon gehe ich aus:

  1. In Ihrer TextBox, für die Sie nur numerische Eingaben zulassen möchten, ist die Eigenschaft Text zunächst auf einen gültigen Zahlenwert (z. B. 2,7172) eingestellt.

  2. Ihr Textfeld ist ein untergeordnetes Element Ihres Hauptfensters

  3. Ihr Hauptfenster ist von der Klasse Window1

  4. Ihr TextBox-Name ist numericTB

Die Grundidee:

  1. Hinzufügen: private string previousText; zu Ihrer Hauptfensterklasse (Window1)

  2. Hinzufügen: previousText = numericTB.Text; in den Konstruktor Ihres Hauptfensters

  3. Erstellen Sie einen Handler für das numericTB.TextChanged-Ereignis, der etwa so aussehen sollte:

    private void numericTB_TextChanged(object sender, TextChangedEventArgs e)
    {
        double num = 0;
        bool success = double.TryParse(((TextBox)sender).Text, out num);
        if (success & num >= 0)
            previousText = ((TextBox)sender).Text;
        else
            ((TextBox)sender).Text = previousText;
    }

Dadurch wird previousText auf numericTB.Text gesetzt, solange es gültig ist, und numericTB.Text wird auf den letzten gültigen Wert gesetzt, wenn der Benutzer etwas schreibt, was Ihnen nicht gefällt. Natürlich ist dies nur eine Grundidee, und sie ist nur "idiotensicher", nicht "idiotensicher". Es behandelt zum Beispiel nicht den Fall, dass der Benutzer mit Leerzeichen herumspielt. Hier ist also eine vollständige Lösung, die meiner Meinung nach "idiotensicher" ist, und wenn ich falsch liege, sagen Sie es mir bitte:

  1. Inhalt der Datei Window1.xaml:

    <Window x:Class="IdiotProofNumericTextBox.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="300">
        <Grid>
            <TextBox Height="30" Width="100" Name="numericTB" TextChanged="numericTB_TextChanged"/>
        </Grid>
    </Window>
  2. Inhalt der Datei Window.xaml.cs:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace IdiotProofNumericTextBox
    {
        public partial class Window1 : Window
        {
            private string previousText;
    
            public Window1()
            {
                InitializeComponent();
                previousText = numericTB.Text;
            }
    
            private void numericTB_TextChanged(object sender, TextChangedEventArgs e)
            {
                if (string.IsNullOrEmpty(((TextBox)sender).Text))
                    previousText = "";
                else
                {
                    double num = 0;
                    bool success = double.TryParse(((TextBox)sender).Text, out num);
                    if (success & num >= 0)
                    {
                        ((TextBox)sender).Text.Trim();
                        previousText = ((TextBox)sender).Text;
                    }
                    else
                    {
                        ((TextBox)sender).Text = previousText;
                        ((TextBox)sender).SelectionStart = ((TextBox)sender).Text.Length;
                    }
                }
            }
        }
    }

Und das war's. Wenn Sie viele TextBoxen haben, empfehle ich Ihnen, ein CustomControl zu erstellen, das von TextBox erbt, so dass Sie previousText und numericTB_TextChanged in eine separate Datei packen können.

6voto

Danny Beckett Punkte 19352

Dies ist der einzige benötigte Code:

void MyTextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
    e.Handled = new Regex("[^0-9]+").IsMatch(e.Text);
}

Damit können nur Zahlen in das Textfeld eingegeben werden.

Um einen Dezimalpunkt oder ein Minuszeichen zuzulassen, können Sie den regulären Ausdruck ändern in [^0-9.-]+ .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X