Надежная проверка в WPF
-
09-06-2019 - |
Вопрос
У меня есть текстовое поле с привязкой к базе данных в моем приложении, вот так:(Тип Height
является decimal?
)
<TextBox Text="{Binding Height, UpdateSourceTrigger=PropertyChanged,
ValidatesOnExceptions=True,
Converter={StaticResource NullConverter}}" />
public class NullableConverter : IValueConverter {
public object Convert(object o, Type type, object parameter, CultureInfo culture) {
return o;
}
public object ConvertBack(object o, Type type, object parameter, CultureInfo culture) {
if (o as string == null || (o as string).Trim() == string.Empty)
return null;
return o;
}
}
Настроенные таким образом, любые непустые строки, которые не могут быть преобразованы в десятичные, приводят к ошибке проверки, которая немедленно выделит текстовое поле.Однако текстовое поле все равно может потерять фокус и оставаться в недопустимом состоянии.То, что я хотел бы сделать, это либо:
- Не позволяйте текстовому полю терять фокус до тех пор, пока оно не будет содержать допустимое значение.
- Верните значение в текстовом поле к последнему допустимому значению.
Каков наилучший способ сделать это?
Обновить:
Я нашел способ сделать #2.Мне это не нравится, но это работает:
private void TextBox_LostKeyboardFocus(object sender, RoutedEventArgs e) {
var box = sender as TextBox;
var binding = box.GetBindingExpression(TextBox.TextProperty);
if (binding.HasError)
binding.UpdateTarget();
}
Кто-нибудь знает, как сделать это лучше?(Или сделайте #1.)
Решение
Вы можете принудительно удерживать фокус клавиатуры на TextBox
путем обращения с PreviewLostKeyBoardFocus
событие, подобное этому:
<TextBox PreviewLostKeyboardFocus="TextBox_PreviewLostKeyboardFocus" />
private void TextBox_PreviewLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) {
e.Handled = true;
}
Другие советы
Мне кажется, что вы захотите обработать два события:
Сфокусировался:Сработает, когда текстовое поле получит фокус.Вы можете сохранить начальное значение поля.
Потерянный фокус:Сработает, когда текстовое поле потеряет фокус.На этом этапе вы можете выполнить проверку и решить, хотите ли вы выполнить откат или нет.