2009-05-18 6 views
5

Disons que j'ai une classe simplela liaison de données et lancer exception setter

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; 
    } 
    } 
} 

Je veux installer une liaison pour cette classe:

txtAge.DataBindings.Add("Text", dataSource, "Name"); 

Maintenant, si j'entre valeur d'âge incorrect dans la zone de texte (disons 200) l'exception dans le setter sera avalée et je ne serai pas capable de faire quoi que ce soit jusqu'à ce que je corrige la valeur dans la zone de texte. Je veux dire que la zone de texte ne sera pas en mesure de perdre le focus. Tout est silencieux - pas d'erreurs - vous ne pouvez rien faire (même fermer le formulaire ou l'application entière) jusqu'à ce que vous corrigiez la valeur.

Cela semble être un bug, mais la question est: qu'est-ce qu'une solution de contournement pour cela?

+1

Existe-t-il une raison pour laquelle vous lancez une exception plutôt que d'implémenter IDataErrorInfo? Je pense que ce dernier est l'approche la plus idiomatique dans WinForms (et il fonctionne encore bien dans WPF). –

Répondre

3

Ok, voici la solution:

Nous devons gérer l'événement BindingComplete de BinsingSource, CurrencyManager ou classe BindingBanagerBase. Le code peut ressembler à ceci:

/* 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(); 
    } 
} 
+0

huuh ... pensez à implémenter IDataErrorInfo –