Ligação de dados e lançando exceção em setter
-
22-08-2019 - |
Pergunta
Vamos dizer que eu tenho uma classe simples
public class Person
{
public string Name { get; set; }
private int _age;
public int Age
{
get { return _age; }
set
{
if(value < 0 || value > 150)
throw new ValidationException("Person age is incorrect");
_age = value;
}
}
}
Então eu quero configurar uma ligação para esta classe:
txtAge.DataBindings.Add("Text", dataSource, "Name");
Agora, se eu entrar valor de idade incorreta na caixa de texto (digamos 200) a exceção no setter será engolido e não vou ser capaz de fazer qualquer coisa até que eu corrigir o valor na caixa de texto. Quero dizer a caixa de texto não será capaz de foco solto. É tudo em silêncio - sem erros -. Você simplesmente não pode fazer nada (nem perto a forma ou o aplicativo inteiro) até que corrija o valor
Parece que um bug, mas a questão é: o que é uma solução para este
Solução
Ok, aqui está a solução:
Precisamos lidar com eventos BindingComplete de BinsingSource, CurrencyManager ou classe BindingBanagerBase. O código pode ficar assim:
/* Note the 4th parameter, if it is not set, the event will not be fired.
It seems like an unexpected behavior, as this parameter is called
formattingEnabled and based on its name it shouldn't affect BindingComplete
event, but it does. */
txtAge.DataBindings.Add("Text", dataSource, "Name", true)
.BindingManagerBase.BindingComplete += BindingManagerBase_BindingComplete;
...
void BindingManagerBase_BindingComplete(
object sender, BindingCompleteEventArgs e)
{
if (e.Exception != null)
{
// this will show message to user, so it won't be silent anymore
MessageBox.Show(e.Exception.Message);
// this will return value in the bound control to a previous correct value
e.Binding.ReadValue();
}
}