14

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?

Enpeng
  • 33
  • 3
Jiew Meng
  • 84,767
  • 185
  • 495
  • 805
  • Possible duplicate of [How do I get a TextBox to only accept numeric input in WPF?](https://stackoverflow.com/questions/1268552/how-do-i-get-a-textbox-to-only-accept-numeric-input-in-wpf) – StayOnTarget Nov 06 '19 at 19:43

5 Answers5

18

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

  • 2
    this wont handle blank spaces . how can i handle dem? – Kuntady Nithesh Jan 20 '12 at 10:13
  • 1
    IsTextNumeric returns true for non numeric text. A more readable solution would be to change the regex to [0-9] and set e.Handled = !IsTextNumeric, so the event is bubbled up when the text is numeric. That or change the method name to IsTextNotNumeric :) – Rob Gray Apr 22 '12 at 22:35
  • 1
    http://stackoverflow.com/a/1268648/419348 It introduces the same method. Moreover, it prevent pasting incorrect data. – AechoLiu Oct 29 '14 at 05:42
17

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}">
Andrei Pana
  • 4,484
  • 1
  • 26
  • 27
9

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;    
}
kumar Gouraw
  • 121
  • 1
  • 2
0

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;
        }
    }
Gaurav Panwar
  • 974
  • 10
  • 11
0

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