Validação Forte no WPF
-
09-06-2019 - |
Pergunta
Eu tenho um TextBox databound em meu aplicativo assim:(O tipo de 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;
}
}
Configuradas desta forma, quaisquer strings não vazias que não possam ser convertidas em decimal resultam em um erro de validação que destacará imediatamente a caixa de texto.No entanto, o TextBox ainda pode perder o foco e permanecer em um estado inválido.O que eu gostaria de fazer é:
- Não permitir que o TextBox perca o foco até que contenha um valor válido.
- Reverta o valor no TextBox para o último valor válido.
Qual é a melhor maneira de fazer isso?
Atualizar:
Eu encontrei uma maneira de fazer o número 2.Não adoro, mas 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();
}
Alguém sabe como fazer isso melhor?(Ou faça o número 1.)
Solução
Você pode forçar o foco do teclado a permanecer no TextBox
manipulando o PreviewLostKeyBoardFocus
evento como este:
<TextBox PreviewLostKeyboardFocus="TextBox_PreviewLostKeyboardFocus" />
private void TextBox_PreviewLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) {
e.Handled = true;
}
Outras dicas
Parece-me que você desejará lidar com dois eventos:
Ter foco:Será acionado quando a caixa de texto ganhar foco.Você pode armazenar o valor inicial da caixa.
Foco perdido:Será acionado quando a caixa de texto perder o foco.Neste ponto você pode fazer sua validação e decidir se deseja reverter ou não.