Jiew Meng
Jiew Meng

Reputation: 88197

Allow only numeric entry in WPF Text Box

I will like to validate user entry to ensure they are integers. How can I do it? I thought of using IDataErrorInfo which seems like the "correct" way to do validation in WPF. So I tried implementing it, in my ViewModel.

But the thing is my text box is bound to an integer field, and there isn't any need to validate if an int is an int. I noticed that WPF automatically adds a red border around the textbox to notify the user of the error. The underlying property doesn't change to an invalid value. But I would like to notify the user of this. How can I do it?

Upvotes: 14

Views: 71736

Answers (5)

Dlear Ahmad
Dlear Ahmad

Reputation: 41

Here is how to create a numeric field in WPF, using the regular expressions.

XAML:

<TextBox PreviewTextInput="NumberValidationTextBox"></TextBox>

Code behind:

private void NumberValidationTextBox(object sender, TextCompositionEventArgs e)
{
Regex regex = new Regex("[^0-9]+");
e.Handled = regex.IsMatch(e.Text);
}

Upvotes: 0

Gaurav Panwar
Gaurav Panwar

Reputation: 1118

if you are working in WPF Better to use PreviewTextInput event which support all platforms and from presentationcore.dll

here is the example:

private void TextBox_PreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
    {
        if ((e.Text) == null || !(e.Text).All(char.IsDigit))
        {
            e.Handled = true;
        }
    }

Upvotes: 0

kumar Gouraw
kumar Gouraw

Reputation: 121

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

Upvotes: 9

Magnus Gudmundsson
Magnus Gudmundsson

Reputation: 556

Another way is simply to not allow values that are not integers. The following implementation is a little bit sucky, and I would like to abstract it later on in order for it to be more reusable, but here is what I did:

in the code behind in my view (I know this is might hurt if you are a hardcore mvvm ;o) ) I defined the following functions :

  private void NumericOnly(System.Object sender, System.Windows.Input.TextCompositionEventArgs e)
{
    e.Handled = IsTextNumeric(e.Text);

}


private static bool IsTextNumeric(string str)
{
    System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex("[^0-9]");
    return reg.IsMatch(str);

}

And in the XAML view, every textbox that was only supposed to accept integers was defined like this:

   <TextBox Padding="2"  TextAlignment="Right" PreviewTextInput="NumericOnly" Text="{Binding xxx.yyyy}" MaxLength="1" />

The key attribute being PreviewTextInput

Upvotes: 18

Andrei Pana
Andrei Pana

Reputation: 4502

The red border you've seen is actually a ValidationTemplate, which you can extend and add a info for the user. See this example:

    <UserControl.Resources>
        <ControlTemplate x:Key="validationTemplate">
            <Grid>
                <Label Foreground="Red" HorizontalAlignment="Right" VerticalAlignment="Center">Please insert a integer</Label>
                <Border BorderThickness="1" BorderBrush="Red">
                    <AdornedElementPlaceholder />
                </Border>
            </Grid>
        </ControlTemplate>
    </UserControl.Resources>

<TextBox Name="tbValue" Validation.ErrorTemplate="{StaticResource validationTemplate}">

Upvotes: 16

Related Questions