Разрешить только числовую запись в текстовом поле WPF
Мне нравится проверять запись пользователя, чтобы убедиться, что они целые. Как мне это сделать? Я думал об использовании IDataErrorInfo
, который кажется "правильным" способом проверки в WPF. Поэтому я попытался реализовать его в моей модели ViewModel.
Но мое текстовое поле привязано к целочисленному полю, и нет необходимости проверять, является ли int
int
. Я заметил, что WPF автоматически добавляет красную рамку вокруг текстового поля, чтобы уведомить пользователя об ошибке. Базовое свойство не изменяется на недопустимое значение. Но я хотел бы уведомить пользователя об этом. Как я могу это сделать?
Ответы
Ответ 1
Красная рамка, которую вы видели, на самом деле является ValidationTemplate, которую вы можете расширить и добавить информацию для пользователя. См. Этот пример:
<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}">
Ответ 2
Другой способ - просто не допускать значения, которые не являются целыми.
Следующая реализация немного утомительна, и я хотел бы позже ее абстрагировать, чтобы ее можно было повторно использовать, но вот что я сделал:
в коде, расположенном по моему мнению (я знаю, что это может повредить, если вы хардкор mvvm; o))
Я определил следующие функции:
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);
}
И в представлении XAML каждое текстовое поле, которое должно было принимать только целые числа
был определен следующим образом:
<TextBox Padding="2" TextAlignment="Right" PreviewTextInput="NumericOnly" Text="{Binding xxx.yyyy}" MaxLength="1" />
Ключевым атрибутом является PreviewTextInput
Ответ 3
Мы можем выполнить проверку на событие с измененным текстовым полем.
Следующая реализация предотвращает ввод ввода, отличный от числовой и одной десятичной точки.
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;
}