Pergunta

Ao criar um IVALUECONVERTER personalizado para um campo editável do usuário, a implementação convert é geralmente bastante direta.

A implementação do Convertback não é, pois (na ausência de uma regra de validação explícita), ela deve lidar com a má entrada do usuário (por exemplo, digitar "HI" em um campo de entrada numérica).

Se ocorrer um erro durante a conversão, não parece haver nenhuma maneira de comunicar o erro específico:

  • O Convertback não tem permissão para lançar exceções (se o fizer, o programa termina).
  • Retornar um ValidationError não faz nada.
  • Retornar dependencyProperty.UnSetValue (que os documentos sugerem) resulta em falha silenciosa (nenhuma interface do erro é mostrada ao usuário, mesmo se você configurou um modelo de erro).
  • O retorno do valor não convertido original faz com que a interface do usuário do erro seja mostrada, mas com texto de erro enganoso.

Alguém conhece uma maneira melhor de lidar com esse tipo de coisa?

(Nota: Ao definir uma validação personalizada, funcionaria, não acho que seja uma boa resposta, pois basicamente teria que duplicar a lógica de conversão para descobrir o erro de qualquer maneira.)

Foi útil?

Solução

Você pode evitar duplicar a lógica, fazendo com que a primeira etapa da regra de validação seja chamar o conversor de valor para descobrir se o valor que é validado é utilizável.

Obviamente, isso casal suas regras de validação para seus conversores de valor, a menos que você faça uma regra de validação que pesquise a ligação para descobrir qual conversor de valor está em uso. Mas se você começar a seguir esse caminho, mais tarde, provavelmente, provavelmente ocorrerá para você, como deve ser "espere, se eu estiver usando o MVVM, o que estou fazendo estragando com conversores de valor?"

Editar:

Se o seu viewmodel implementar IDataErrorInfo, que é realmente a única maneira de viver, é relativamente simples conectar um conversor de valor em um criador de propriedades sem escrever muita lógica de validação específica da propriedade.

Na sua classe ViewModel, crie dois campos privados:

Dictionary<string, string> Errors;
Dictionary<string, IValueConverter>;

Crie -os (e preencha o segundo) no construtor. Também para IDataErrorInfo:

public string this[string columnName]
{
    return Errors.ContainsKey(columnName)
       ? Errors[columnName]
       : null;
}

Agora implemente um método como este:

private bool ValidateProperty(string propertyName, Type targetType, object value)
{
   Errors[propertyName] = null;
   if (!Converters.ContainsKey(propertyName))
   {
      return true;
   }
   try
   {
      object result = Converters[propertyName].ConvertBack(value, targetType, null, null)
      return true;
   }
   catch (Exception e)
   {
      Errors[propertyName] = e.Message;
      return false;
   }
}

Agora seu setter de propriedade se parece com o seguinte:

public SomeType SomeProperty
{
   set
   {
      if (ValidateProperty("SomeProperty", typeof(SomeType), value))
      {
         _SomeProperty = value;
      }
   }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top