Fuerte validación en WPF
-
09-06-2019 - |
Pregunta
Tengo un TextBox enlazado a datos en mi aplicación así:(El tipo de Height
es 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;
}
}
Configurado de esta manera, cualquier cadena que no esté vacía y que no se pueda convertir a decimal dará como resultado un error de validación que resaltará inmediatamente el cuadro de texto.Sin embargo, el TextBox aún puede perder el foco y permanecer en un estado no válido.Lo que me gustaría hacer es:
- No permita que el cuadro de texto pierda el foco hasta que contenga un valor válido.
- Revierta el valor en el cuadro de texto al último valor válido.
¿Cuál es la mejor manera de hacer esto?
Actualizar:
Encontré una manera de hacer el n.° 2.No me encanta, pero funciona:
private void TextBox_LostKeyboardFocus(object sender, RoutedEventArgs e) {
var box = sender as TextBox;
var binding = box.GetBindingExpression(TextBox.TextProperty);
if (binding.HasError)
binding.UpdateTarget();
}
¿Alguien sabe cómo hacer esto mejor?(O haz el n.° 1).
Solución
Puede forzar el foco del teclado para que permanezca en el TextBox
manejando el PreviewLostKeyBoardFocus
evento como este:
<TextBox PreviewLostKeyboardFocus="TextBox_PreviewLostKeyboardFocus" />
private void TextBox_PreviewLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) {
e.Handled = true;
}
Otros consejos
Me parece que querrás manejar dos eventos:
Se enfocó:Se activará cuando el cuadro de texto gane foco.Puede almacenar el valor inicial de la caja.
Perdió el enfoque:Se activará cuando el cuadro de texto pierda el foco.En este punto puedes hacer tu validación y decidir si quieres retroceder o no.