irco
irco

Reputation: 981

Input validation on Windows store app

In a windows store App using MVVM I have a TextBox with two way binding that should only allow numeric values. What is the proper procedure using MVVM to simply ignore when a non numeric key is pressed?

The value being changed of the INotifyPropertyChanged only triggers when the textbox loses focus. I basically want instant validation for my Properties. I can't find a proper simple example of this.

Upvotes: 1

Views: 477

Answers (1)

Decade Moon
Decade Moon

Reputation: 34286

Why not create an attached property to contain this behavior? Something like this:

public class TextBoxHelper
{
    public static bool GetRestrictToNumerical(DependencyObject obj)
    {
        return (bool)obj.GetValue(RestrictToNumericalProperty);
    }

    public static void SetRestrictToNumerical(DependencyObject obj, bool value)
    {
        obj.SetValue(RestrictToNumericalProperty, value);
    }

    public static readonly DependencyProperty RestrictToNumericalProperty =
        DependencyProperty.RegisterAttached("RestrictToNumerical", typeof(bool), typeof(TextBoxHelper), new PropertyMetadata(false, onRestrictToNumericalChanged));

    private static void onRestrictToNumericalChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var tb = d as TextBox;
        if (tb == null)
            return;

        if ((bool)e.NewValue)
            tb.KeyDown += tb_KeyDown;
        else
            tb.KeyDown -= tb_KeyDown;
    }

    static void tb_KeyDown(object sender, Windows.UI.Xaml.Input.KeyRoutedEventArgs e)
    {
        e.Handled = e.Key < VirtualKey.Number0 || e.Key > VirtualKey.Number9;
    }
}

You'd use it in your XAML like this:

<Page
    x:Class="App4.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App4"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <TextBox VerticalAlignment="Center" local:TextBoxHelper.RestrictToNumerical="True" InputScope="Number" />
    </Grid>
</Page>

This, in my opinion, is a clean MVVM approach for all input validations that you might be required to do. It's probably overkill for your simple question, but it's good for more sophisticated validations.

Upvotes: 2

Related Questions