Проверка в текстовом поле в WPF
-
20-09-2019 - |
Вопрос
В настоящее время я работаю над приложением WPF, в котором я хотел бы иметь TextBox
в нем могут быть только числовые записи.Я знаю, что могу проверить его содержимое, когда потерял фокус, и заблокировать числовое значение содержимого, но в других приложениях Windows Form мы используем полную блокировку записи любого ввода, кроме числового.Кроме того, мы помещаем этот код в отдельную dll, чтобы ссылаться на него во многих местах.
Вот код в 2008 году, не использующий WPF:
Public Shared Sub BloquerInt(ByRef e As System.Windows.Forms.KeyPressEventArgs, ByRef oTxt As Windows.Forms.TextBox, ByVal intlongueur As Integer)
Dim intLongueurSelect As Integer = oTxt.SelectionLength
Dim intPosCurseur As Integer = oTxt.SelectionStart
Dim strValeurTxtBox As String = oTxt.Text.Substring(0, intPosCurseur) & oTxt.Text.Substring(intPosCurseur + intLongueurSelect, oTxt.Text.Length - intPosCurseur - intLongueurSelect)
If IsNumeric(e.KeyChar) OrElse _
Microsoft.VisualBasic.Asc(e.KeyChar) = System.Windows.Forms.Keys.Back Then
If Microsoft.VisualBasic.AscW(e.KeyChar) = System.Windows.Forms.Keys.Back Then
e.Handled = False
ElseIf strValeurTxtBox.Length < intlongueur Then
e.Handled = False
Else
e.Handled = True
End If
Else
e.Handled = True
End If
Есть ли эквивалентный способ в WPF?Я бы не возражал, если бы это было в стиле, но я новичок в WPF, поэтому стили немного неясны в отношении того, что они могут или не могут делать.
Решение
Вы можете ограничить ввод только числами, используя прикрепленное свойство TextBox.Определите прикрепленное свойство один раз (даже в отдельной dll) и используйте его в любом текстовом поле.Вот прикрепленное свойство:
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
/// <summary>
/// Class that provides the TextBox attached property
/// </summary>
public static class TextBoxService
{
/// <summary>
/// TextBox Attached Dependency Property
/// </summary>
public static readonly DependencyProperty IsNumericOnlyProperty = DependencyProperty.RegisterAttached(
"IsNumericOnly",
typeof(bool),
typeof(TextBoxService),
new UIPropertyMetadata(false, OnIsNumericOnlyChanged));
/// <summary>
/// Gets the IsNumericOnly property. This dependency property indicates the text box only allows numeric or not.
/// </summary>
/// <param name="d"><see cref="DependencyObject"/> to get the property from</param>
/// <returns>The value of the StatusBarContent property</returns>
public static bool GetIsNumericOnly(DependencyObject d)
{
return (bool)d.GetValue(IsNumericOnlyProperty);
}
/// <summary>
/// Sets the IsNumericOnly property. This dependency property indicates the text box only allows numeric or not.
/// </summary>
/// <param name="d"><see cref="DependencyObject"/> to set the property on</param>
/// <param name="value">value of the property</param>
public static void SetIsNumericOnly(DependencyObject d, bool value)
{
d.SetValue(IsNumericOnlyProperty, value);
}
/// <summary>
/// Handles changes to the IsNumericOnly property.
/// </summary>
/// <param name="d"><see cref="DependencyObject"/> that fired the event</param>
/// <param name="e">A <see cref="DependencyPropertyChangedEventArgs"/> that contains the event data.</param>
private static void OnIsNumericOnlyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
bool isNumericOnly = (bool)e.NewValue;
TextBox textBox = (TextBox)d;
if (isNumericOnly)
{
textBox.PreviewTextInput += BlockNonDigitCharacters;
textBox.PreviewKeyDown += ReviewKeyDown;
}
else
{
textBox.PreviewTextInput -= BlockNonDigitCharacters;
textBox.PreviewKeyDown -= ReviewKeyDown;
}
}
/// <summary>
/// Disallows non-digit character.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">An <see cref="TextCompositionEventArgs"/> that contains the event data.</param>
private static void BlockNonDigitCharacters(object sender, TextCompositionEventArgs e)
{
foreach (char ch in e.Text)
{
if (!Char.IsDigit(ch))
{
e.Handled = true;
}
}
}
/// <summary>
/// Disallows a space key.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">An <see cref="KeyEventArgs"/> that contains the event data.</param>
private static void ReviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Space)
{
// Disallow the space key, which doesn't raise a PreviewTextInput event.
e.Handled = true;
}
}
}
Вот как его использовать (замените «controls» на свое собственное пространство имен):
<TextBox controls:TextBoxService.IsNumericOnly="True" />
Другие советы
Вы можете поместить проверку в свою привязку
<TextBox>
<TextBox.Text>
<Binding Path="CategoriaSeleccionada.ColorFondo"
UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<utilities:RGBValidationRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
Посмотрите на этот пример (моей программы): вы помещаете проверку внутри привязки вот так.С помощью UpdateSourceTrigger вы можете изменить время обновления привязки (потеря фокуса при каждом изменении...)
Ну, валидация — это класс, я приведу вам пример:
class RGBValidationRule : ValidationRule
{
public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
{
// Here you make your validation using the value object.
// If you want to check if the object is only numbers you can
// Use some built-in method
string blah = value.ToString();
int num;
bool isNum = int.TryParse(blah, out num);
if (isNum) return new ValidationResult(true, null);
else return new ValidationResult(false, "It's no a number");
}
}
Короче говоря, выполните работу внутри этого метода и верните новый ValidationResult.Первый параметр — логическое значение, true, если проверка хорошая, и false, если нет.Второй параметр — это всего лишь информационное сообщение.
Я думаю, что это основы проверки текстового поля.
Надеюсь, это поможет.
РЕДАКТИРОВАТЬ:Извините, я не знаю VB.NET, но думаю, что код C# довольно прост.