Search code examples
windowswindows-8numerictile

Alternatives for Numericbox in Windows 8 apps?


I am trying to find a good alternative to Numericbox in a windows 8 tile application. I tried using the same numericbox that exists for windows forms but got an error saying these are not supported(?) by windows 8 applications. I noticed that the TextBox element for tile applications has a InputScope that can be set to "Number", but it still allows the user to type in whatever character he wants to. I assume the InputScope does not do what I think it does.

I am currently managing with the textbox, but because I am doing calculations the text has to constantly be converted to decimal and then back to text when I want to update the interface, in addition to having to execute several checks to make sure the user does not enter non-numeric characters. This is getting extremely tedious and being very familiar with Windows Form this seems to be a step in the wrong direction. I must be missing something obvious?


Solution

  • I am not familiar with NumericTextBox, but here is a simple C#/XAML implementation that allows only digits and the decimal character.

    All it does is override the OnKeyDown event; based on the key being pressed, it either allows or disallows the event to reach the base TextBox class.

    I should note that this implementation is for Windows Store apps - I believe your question is about that type of app, but I am not 100% sure.

    public class MyNumericTextBox : TextBox
    {
        protected override void OnKeyDown(KeyRoutedEventArgs e)
        {
            HandleKey(e);
    
            if (!e.Handled)
                base.OnKeyDown(e);
        }
    
        bool _hasDecimal = false;
        private void HandleKey(KeyRoutedEventArgs e)
        {
            switch (e.Key)
            {
                // allow digits
                // TODO: keypad numeric digits here
                case Windows.System.VirtualKey.Number0:
                case Windows.System.VirtualKey.Number1:
                case Windows.System.VirtualKey.Number2:
                case Windows.System.VirtualKey.Number3:
                case Windows.System.VirtualKey.Number4:
                case Windows.System.VirtualKey.Number5:
                case Windows.System.VirtualKey.Number6:
                case Windows.System.VirtualKey.Number7:
                case Windows.System.VirtualKey.Number8:
                case Windows.System.VirtualKey.Number9:
                    e.Handled = false;
                    break;
    
                // only allow one decimal
                // TODO: handle deletion of decimal...
                case (Windows.System.VirtualKey)190:    // decimal (next to comma)
                case Windows.System.VirtualKey.Decimal: // decimal on key pad
                    e.Handled = (_hasDecimal == true);
                    _hasDecimal = true;
                    break;
    
                // pass various control keys to base
                case Windows.System.VirtualKey.Up:
                case Windows.System.VirtualKey.Down:
                case Windows.System.VirtualKey.Left:
                case Windows.System.VirtualKey.Right:
                case Windows.System.VirtualKey.Delete:
                case Windows.System.VirtualKey.Back:
                case Windows.System.VirtualKey.Tab:
                    e.Handled = false;
                    break;
    
                default:
                    // default is to not pass key to base
                    e.Handled = true;
                    break;
            }
        }
    }
    

    Here is some sample XAML. Note that it assumes MyNumericTextBox is in the project namespace.

    <StackPanel Background="Black">
        <!-- custom numeric textbox -->
        <local:MyNumericTextBox />
        <!-- normal textbox -->
        <TextBox />
    </StackPanel>