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 a开发者_StackOverflow社区ny 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?
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
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}">
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;
}
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;
}
}
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);
}
精彩评论