Un problème qui vient de m’arriver et qui est assez difficile à anticiper via des tests unitaires est le fait que d’utiliser le binding des controles dans une winform.
Par exemple si j’ai une textbox sur laquelle je veux binder le code d’un produit je vais ecrire :
myTextBox.DataBindings.Add("Text", bindingSource, "ProductCode");
Si maintenant je “refactore” ma classe product et change la propriété [ProductCode] par [Code] pour etre plus simple, tout mon projet sera changé, ça va compiler, sauf la ligne précédente il restera toujours “ProductCode”, etant donné que ce code est directement lié à l’interface graphique il est très difficile de reperer le bug via des tests unitaires avant d’ouvrir le formulaire manuellement, c’est du vecu, c’est plutot vos clients qui vous en parlent en premier :(
pour eviter ce problème, voici une solution :
public static class BindingExtensions
{
public static Binding Add<TSource>(this ControlBindingsCollection controlBindingCollection, string propertyName, object bindingSource, Expression<Func<TSource, object>> expression)
{
return controlBindingCollection.Add(propertyName, bindingSource, expression, false, controlBindingCollection.DefaultDataSourceUpdateMode, null, string.Empty, null);
}
public static Binding Add<TSource>(this ControlBindingsCollection controlBindingCollection, string propertyName, object bindingSource, Expression<Func<TSource, object>> expression, bool formattingEnabled)
{
return controlBindingCollection.Add(propertyName, bindingSource, expression, formattingEnabled, controlBindingCollection.DefaultDataSourceUpdateMode, null, string.Empty, null);
}
public static Binding Add<TSource>(this ControlBindingsCollection controlBindingCollection, string propertyName, object bindingSource, Expression<Func<TSource, object>> expression, bool formattingEnabled, DataSourceUpdateMode updateMode)
{
return controlBindingCollection.Add(propertyName, bindingSource, expression, formattingEnabled, updateMode, null, string.Empty, null);
}
public static Binding Add<TSource>(this ControlBindingsCollection controlBindingCollection, string propertyName, object bindingSource, Expression<Func<TSource, object>> expression, bool formattingEnabled, DataSourceUpdateMode updateMode, object nullValue)
{
return controlBindingCollection.Add(propertyName, bindingSource, expression, formattingEnabled, updateMode, nullValue, string.Empty, null);
}
public static Binding Add<TSource>(this ControlBindingsCollection controlBindingCollection, string propertyName, object bindingSource, Expression<Func<TSource, object>> expression, bool formattingEnabled, DataSourceUpdateMode updateMode, object nullValue, string formatString)
{
return controlBindingCollection.Add(propertyName, bindingSource, expression, formattingEnabled, updateMode, nullValue, formatString, null);
}
public static Binding Add<TSource>(this ControlBindingsCollection controlBindingCollection, string propertyName, object bindingSource, Expression<Func<TSource, object>> expression, bool formattingEnabled, DataSourceUpdateMode updateMode, object nullValue, string formatString, IFormatProvider formatInfo)
{
if (bindingSource == null)
{
throw new ArgumentNullException("dataSource");
}
var dataMemberName = ((expression.Body as UnaryExpression).Operand as MemberExpression).Member.Name;
return controlBindingCollection.Add(propertyName, bindingSource, dataMemberName, formattingEnabled, updateMode, nullValue, formatString, formatInfo);
}
}
J’ai ajouté dans mon projet une classe avec un certain nombre de methodes qui etendent l’objet ControlBindingCollection, la difference est que je ne passe plus le nom de la propriété mais utilise une lambda expression de la manière suivante :
myTextbox.DataBindings.Add<Product>("Text", bindingSource, p => p.ProductCode);
En cas de “refacto”, le nouveau nom de propriété sera changé.
Petit bémol avec cette méthode, il n’est plus question d’utiliser le designer intégré avec visual studio 2008, mais il faut choisir entre la maintenabilité et le confort pour le developpeur. Personnelement je n’utilise plus le designer pour tout ce qui concerne le binding.
Aucun commentaire:
Enregistrer un commentaire