Validation.haserror não aciona novamente se o novo erro entrar enquanto já é verdadeiro
-
25-09-2019 - |
Pergunta
Eu uso o MVVM e meu objeto implementam o idataerrorinfo. Quando uma propriedade é definida, executo métodos de validação personalizados e, se a validação passar, retorno String.Empty, que define validation.haserror como false. Se a validação falhar, a validação.HasError estará definida como true. Eu tenho um estilo que eu uso para "controles necessários" (controles que executarão a validação) e a dica de ferramenta do controle para qualquer que seja o erro assim:
<Style x:Key="RequiredControl" TargetType="{x:Type Control}" >
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip" Value="{Binding (Validation.Errors), Converter={StaticResource ErrorConverter}, RelativeSource={x:Static RelativeSource.Self}}"/>
</Trigger>
</Style.Triggers>
</Style>
E o ErrorConverter:
public class ZynErrorContentConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var errors = value as ReadOnlyObservableCollection<ValidationError>;
if (errors == null) return "";
return errors.Count > 0 ? errors[0].ErrorContent : "";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
O problema é o seguinte: o usuário insere algo inválido ... e a validação.HasError está definido como true. A dica de ferramenta atualiza como deve. Se o usuário tentar corrigir o erro, mas insere um valor que causa um tipo diferente de invalidação, a dica de ferramenta deve mostrar a nova string de erro, mas isso não acontece. O erro mostra o mesmo erro do primeiro erro. Eu sei por que isso acontece (eu acho) ... porque o gatilho não é acionado porque a validação.Haserror nunca muda de verdadeiro -> false -> true.
Alguém tem alguma experiência com este ou alguns conselhos sobre como forçar o gatilho?
Solução
Esta parece ser a resposta: Idataerrorinfo com várias mensagens de erro para uma propriedade
Basicamente, você se liga ao item atual e usa um representante de conteúdo para exibir o erro. Funcionou para o meu código.
Outras dicas
Eu acredito que descobri isso. O culpado é o uso do conversor. Eu estava enfrentando o mesmo problema e o snippet de código de problema era:
<Setter Property="ToolTip"
Value="{Binding RelativeSource={x:Static RelativeSource.Self},
Path=(Validation.Errors),
Converter={StaticResource validationErrorsToStringConverter }}"/>
Eu mudo o trecho para:
<Setter Property="ToolTip"
Value="{Binding RelativeSource={x:Static RelativeSource.Self},
Path=(Validation.Errors)[0].ErrorContent}"/>
e o problema foi resolvido.
Conclusão - Não use um conversor.