How do I get a TextBox to only accept numeric input in WPF?
How do I get a TextBox to only accept numeric input in WPF?
I'm looking to accept digits and the decimal point, but no sign.
I've looked at samples using the NumericUpDown control for WinForms, and this sample of a NumericUpDown custom control from Microsoft. But so far it seems like NumericUpDown (supported by WPF or not) is not going to provide the functionality that I want. The way my app is designed, nobody in their right mind is going to want to mess with the arrows. They don't make any practical sense, in the context of my app.
So I'm looking for a simple way to make a standard WPF TextBox accept only the characters that I want. Is this possible? Is it practical?
Answer by Stephen Wrighton for How do I get a TextBox to only accept numeric input in WPF?
Add in a VALIDATION RULE that when the text changes checks to determine if the data is numeric, and if it is, allows processing to continue, and if it is not, prompts the user that only numeric data is accepted in that field.
Read more here: http://www.codeproject.com/KB/WPF/wpfvalidation.aspx
Answer by Ray for How do I get a TextBox to only accept numeric input in WPF?
Add a preview text input event. Like so:
.
Then inside that set the e.Handled if the text isn't allowed. e.Handled = !IsTextAllowed(e.Text);
I use a simple regex in IsTextAllowed to see if I should allow what they've typed. In my case I only want to allow numbers, dots and dashes.
private static bool IsTextAllowed(string text) { Regex regex = new Regex("[^0-9.-]+"); //regex that matches disallowed text return !regex.IsMatch(text); }
If you want to prevent pasting of incorrect data hook up the DataObject.Pasting event DataObject.Pasting="TextBoxPasting"
as shown here (code excerpted):
// Use the DataObject.Pasting Handler private void TextBoxPasting(object sender, DataObjectPastingEventArgs e) { if (e.DataObject.GetDataPresent(typeof(String))) { String text = (String)e.DataObject.GetData(typeof(String)); if (!IsTextAllowed(text)) { e.CancelCommand(); } } else { e.CancelCommand(); } }
Answer by Brian Lagunas for How do I get a TextBox to only accept numeric input in WPF?
The Extented WPF Toolkit has one: NumericUpDown
Answer by user666535 for How do I get a TextBox to only accept numeric input in WPF?
I will assume that:
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).
your Textbox is a child of your main window
your main window is of class Window1
your TextBox name is numericTB
Basic idea:
Add:
private string previousText;
to your main window class (Window1)Add:
previousText = numericTB.Text;
to your main window constructorcreate handler for 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 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 case in which user messes with spaces, for example. So here is complete solution which I think is "idiot proof", and if I'm wrong please tell me:
content of your Window1.xaml file:
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; } } } } }
Ant that's it. If you have many TextBoxes than I recommend creating CustomControl that inherits from TextBox, so you can wrap previousText and numericTB_TextChanged up in a separate file.
Happy coding.
Answer by Novice for How do I get a TextBox to only accept numeric input in WPF?
e.Handled = (int)e.Key >= 43 || (int)e.Key <= 34;
in preview keydown event of textbox.
Answer by Johnny for How do I get a TextBox to only accept numeric input in WPF?
Private Sub DetailTextBox_PreviewTextInput(ByVal sender As Object, ByVal e As System.Windows.Input.TextCompositionEventArgs) Handles DetailTextBox.PreviewTextInput If _IsANumber Then If Not Char.IsNumber(e.Text) Then e.Handled = True End If End If End Sub
Answer by Wil P for How do I get a TextBox to only accept numeric input in WPF?
Used some of what was already here and put my own twist on it using a behavior so I don't have to propogate this code throughout a ton of Views...
public class AllowableCharactersTextBoxBehavior : Behavior { public static readonly DependencyProperty RegularExpressionProperty = DependencyProperty.Register("RegularExpression", typeof(string), typeof(AllowableCharactersTextBoxBehavior), new FrameworkPropertyMetadata(".*")); public string RegularExpression { get { return (string)base.GetValue(RegularExpressionProperty); } set { base.SetValue(RegularExpressionProperty, value); } } public static readonly DependencyProperty MaxLengthProperty = DependencyProperty.Register("MaxLength", typeof(int), typeof(AllowableCharactersTextBoxBehavior), new FrameworkPropertyMetadata(int.MinValue)); public int MaxLength { get { return (int)base.GetValue(MaxLengthProperty); } set { base.SetValue(MaxLengthProperty, value); } } protected override void OnAttached() { base.OnAttached(); AssociatedObject.PreviewTextInput += OnPreviewTextInput; DataObject.AddPastingHandler(AssociatedObject, OnPaste); } private void OnPaste(object sender, DataObjectPastingEventArgs e) { if (e.DataObject.GetDataPresent(DataFormats.Text)) { string text = Convert.ToString(e.DataObject.GetData(DataFormats.Text)); if (!IsValid(text, true)) { e.CancelCommand(); } } else { e.CancelCommand(); } } void OnPreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e) { e.Handled = !IsValid(e.Text, false); } protected override void OnDetaching() { base.OnDetaching(); AssociatedObject.PreviewTextInput -= OnPreviewTextInput; DataObject.RemovePastingHandler(AssociatedObject, OnPaste); } private bool IsValid(string newText, bool paste) { return !ExceedsMaxLength(newText, paste) && Regex.IsMatch(newText, RegularExpression); } private bool ExceedsMaxLength(string newText, bool paste) { if (MaxLength == 0) return false; return LengthOfModifiedText(newText, paste) > MaxLength; } private int LengthOfModifiedText(string newText, bool paste) { var countOfSelectedChars = this.AssociatedObject.SelectedText.Length; var caretIndex = this.AssociatedObject.CaretIndex; string text = this.AssociatedObject.Text; if (countOfSelectedChars > 0 || paste) { text = text.Remove(caretIndex, countOfSelectedChars); return text.Length + newText.Length; } else { var insert = Keyboard.IsKeyToggled(Key.Insert); return insert && caretIndex < text.Length ? text.Length : text.Length + newText.Length; } } }
Here is the relevant view code.
Answer by kumar Gouraw for How do I get a TextBox to only accept numeric input in WPF?
We can do validation on text box changed event. The following implementation prevents keypress input other than numeric and one decimal point.
private void textBoxNumeric_TextChanged(object sender, TextChangedEventArgs e) { TextBox textBox = sender as TextBox; Int32 selectionStart = textBox.SelectionStart; Int32 selectionLength = textBox.SelectionLength; String newText = String.Empty; int count = 0; foreach (Char c in textBox.Text.ToCharArray()) { if (Char.IsDigit(c) || Char.IsControl(c) || (c == '.' && count == 0)) { newText += c; if (c == '.') count += 1; } } textBox.Text = newText; textBox.SelectionStart = selectionStart <= textBox.Text.Length ? selectionStart : textBox.Text.Length; }
Answer by WPFK for How do I get a TextBox to only accept numeric input in WPF?
The Event handler is preview text input. Here regular expression matches the text input only if it is not a number, then it is not made to entry textbox. If you want only alphabets then replace the regular expression as [^a-zA-Z]
.
XAML
XAML.CS FILE
using System.Text.RegularExpressions; private void NumberValidationTextBox(object sender, TextCompositionEventArgs e) { Regex regex = new Regex("[^0-9]+"); e.Handled = regex.IsMatch(e.Text); }
Answer by glenatron for How do I get a TextBox to only accept numeric input in WPF?
This is an old question, but I was working with an unbound box for a simple project I was working on, so I couldn't use the standard binding approach. Consequently I created a simple hack that others might find quite handy by simply extending the existing TextBox control:
namespace MyApplication.InterfaceSupport { public class NumericTextBox : TextBox { public NumericTextBox() : base() { TextChanged += OnTextChanged; } public void OnTextChanged(object sender, TextChangedEventArgs changed) { if (!String.IsNullOrWhiteSpace(Text)) { try { int value = Convert.ToInt32(Text); } catch (Exception e) { MessageBox.Show(String.Format("{0} only accepts numeric input.", Name)); Text = ""; } } } public int? Value { set { if (value != null) { this.Text = value.ToString(); } else Text = ""; } get { try { return Convert.ToInt32(this.Text); } catch (Exception ef) { // not numeric. } return null; } } } }
Obviously, for a floating type, you would want to parse it as a float and so on. Principles apply.
Then in the XAML file you need to include the relevant namespace:
After that you can use it as a regular control:
Answer by Hamzeh Soboh for How do I get a TextBox to only accept numeric input in WPF?
I allowed numpad numbers and backspace:
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); }
Hope it helps.
Answer by Klaus for How do I get a TextBox to only accept numeric input in WPF?
This is an improved solution of WilPs answer. My improvements are:
- Improved behaviour on Del and Backspace buttons
- Added
EmptyValue
property, if empty string is inappropriate - Fixed some minor typos
/// /// Regular expression for Textbox with properties: /// , /// , /// . /// public class TextBoxInputRegExBehaviour : Behavior { #region DependencyProperties public static readonly DependencyProperty RegularExpressionProperty = DependencyProperty.Register("RegularExpression", typeof(string), typeof(TextBoxInputRegExBehaviour), new FrameworkPropertyMetadata(".*")); public string RegularExpression { get { return (string)GetValue(RegularExpressionProperty); } set { SetValue(RegularExpressionProperty, value); } } public static readonly DependencyProperty MaxLengthProperty = DependencyProperty.Register("MaxLength", typeof(int), typeof(TextBoxInputRegExBehaviour), new FrameworkPropertyMetadata(int.MinValue)); public int MaxLength { get { return (int)GetValue(MaxLengthProperty); } set { SetValue(MaxLengthProperty, value); } } public static readonly DependencyProperty EmptyValueProperty = DependencyProperty.Register("EmptyValue", typeof(string), typeof(TextBoxInputRegExBehaviour), null); public string EmptyValue { get { return (string)GetValue(EmptyValueProperty); } set { SetValue(EmptyValueProperty, value); } }
0 comments:
Post a Comment