How do I get a TextBox to only accept numeric input in WPF?

后端 未结 30 2311
悲哀的现实
悲哀的现实 2020-11-22 03:40

I\'m looking to accept digits and the decimal point, but no sign.

I\'ve looked at samples using the NumericUpDown control for Windows Forms, and this sample of a Num

30条回答
  •  孤独总比滥情好
    2020-11-22 03:57

    I will assume that:

    1. Your TextBox for which you want to allow numeric input only has its Text property initially set to some valid number value (for example, 2.7172).

    2. Your Textbox is a child of your main window

    3. Your main window is of class Window1

    4. Your TextBox name is numericTB

    Basic idea:

    1. Add: private string previousText; to your main window class (Window1)

    2. Add: previousText = numericTB.Text; to your main window constructor

    3. Create a handler for the numericTB.TextChanged event to be something like this:

      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;
      }
      

    This will keep setting previousText to numericTB.Text as long as it is valid, and set numericTB.Text to its last valid value if the user writes something that you don't like. Of course, this is just basic idea, and it is just "idiot resistant", not "idiot proof". It doesn't handle the case in which the user messes with spaces, for example. So here is a complete solution which I think is "idiot proof", and if I'm wrong please tell me:

    1. Content of your Window1.xaml file:

      
          
              
          
      
      
    2. Content of your Window.xaml.cs file:

      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;
                      }
                  }
              }
          }
      }
      

    And that's it. If you have many TextBoxes then I recommend creating a CustomControl that inherits from TextBox, so you can wrap previousText and numericTB_TextChanged up in a separate file.

提交回复
热议问题