6

I'm building a form in a C# WinRT app, and I'd like to restrict the characters in one of the TextBox components to numerals only. (This TextBox would be for a user to enter a year into.)

I've searched for a while, but haven't been able to figure this one out without setting up an event listener on the TextChanged event, and inspecting the text property on every key press. Is there a way to simply say that a user can only enter specific characters into a TextBox?

6 Answers 6

8

The simplest thing that could possibly work is to bind to the OnTextChanged event and modify the text according to your rules.

 <TextBox x:Name="TheText" TextChanged="OnTextChanged" MaxLength="4"/> 
 private void OnTextChanged(object sender, TextChangedEventArgs e) { if (TheText.Text.Length == 0) return; var text = TheText.Text; int result; var isValid = int.TryParse(text, out result); if (isValid) return; TheText.Text = text.Remove(text.Length - 1); TheText.SelectionStart = text.Length; } 

However, I'd shy away from this approach since the mantra of Metro is touch first UI and you can easy do it in a touch first manner with a FlipView control.

Sign up to request clarification or add additional context in comments.

1 Comment

Marking this as the answer as it mostly solves the problem I was having. This will restrict the TextBox to only displaying numbers. However, I've since revisited this part of my app, and replaced the year field with a ComboBox, to sidestep the problem entirely. (I've got a fixed range of years possible, so I don't know why I didn't use a ComboBox in the first place.)
6

Try setting TextBox.InputScope property to InputScopeNameValue.Number, as mentioned in Guidelines and checklist for text input in MSDN.

3 Comments

This is cool, and (sort-of) exists in WPF as well. Didn't know about this one. Thanks!
This kinda works, but won't do exactly what I'm trying to accomplish. It looks like the InputScope property serves more as a hint to the system as to which soft keyboard the system should display, but it won't create a masked TextBox that limits the inputs. (Finally found this thread in the MSDN forums - link below, see post from Chipalo Street, from Thursday, March 22, 2012 5:49 PM). social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/…
Ah, seems like I misunderstood the documentation. Thanks for pointing this out.
0

Valid Year

DateTime newDate; var validYear = DateTime.TryParseExact("2012", "yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out newDate); //valid 

Invalid Year

var validYear = DateTime.TryParseExact("0000", "yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out newDate); //invalid 

Comments

0

This seems to work for me:

 private void TextBox_KeyDown(object sender, KeyRoutedEventArgs e) { if ((e.Key < VirtualKey.Number0) || (e.Key > VirtualKey.Number9)) { // If it's not a numeric character, prevent the TextBox from handling the keystroke e.Handled = true; } } 

See the documentation for the VirtualKey enumeration for all the values.

Comments

0

Based on a posting at link, adding the tab to allow navigation.

private void decimalTextBox_KeyDown(object sender, KeyRoutedEventArgs e) { bool isGoodData; // flag to make the flow clearer. TextBox theTextBox = (TextBox)sender; // the sender is a textbox if (e.Key>= Windows.System.VirtualKey.Number0 && e.Key <= Windows.System.VirtualKey.Number9) // allow digits isGoodData = true; else if (e.Key == Windows.System.VirtualKey.Tab) isGoodData = true; else if (e.Key >= Windows.System.VirtualKey.NumberPad0 && e.Key <= Windows.System.VirtualKey.NumberPad9) // allow digits isGoodData = true; else if (e.Key == Windows.System.VirtualKey.Decimal || (int)e.Key == 190) // character is a decimal point, 190 is the keyboard period code // which is not in the VirtualKey enumeration { if (theTextBox.Text.Contains(".")) // search for a current point isGoodData = false; // only 1 decimal point allowed else isGoodData = true; // this is the only one. } else if (e.Key == Windows.System.VirtualKey.Back) // allow backspace isGoodData = true; else isGoodData = false; // everything else is bad if (!isGoodData) // mark bad data as handled e.Handled = true; } 

1 Comment

Shift-4, which should be a dollar sign, is not filtered out with this code. The 4 key is seen and accepted as a digit. See this question: stackoverflow.com/questions/13001215/… where various methods are shown for detecting the shift, control, etc., keys.
-2

Use a MaskedTextBox control. For numerals only, just use the Mask property to specify the characters and the length, if any. e.g. if you want only five numbers to be entered, you set the mask property to "00000". Simple as that. Windows handles the restriction for you.

3 Comments

Is there a MaskedTextBox for WinRT?
@RitchMelton I don't know presently. I guess the answer should be yes.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.