Erros durante a conversão de valor
-
22-09-2019 - |
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.)
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;
}
}
}