Avec XAML on utilise souvent des Converters lors d’un Binding pour adapter la donnée source vers le type destination. Par exemple le Converter BooleanToVisibilityConverter convertit une valeur booléenne en une valeur de l’énumération Visibility.

Ce mécanisme est très pratique mais on peut se retrouver rapidement avec beaucoup de converters du type :

  • BooleanToVisibilityConverter
  • InverseBooleanConverter
  • EnumerableToBooleanConverter
  • etc.

Au lieu de créer des Converters spécifiques à chaque cas il vaut mieux essayer de les rendre génériques afin de les réutiliser dans un maximum de cas et ainsi éviter leur multiplication. Par exemple les converters ci-dessus peuvent se résumer en un seul Converter : BooleanToValueConverter. A chaque fois la source est une expression booléenne (égal vrai, est null, est vide), seule la valeur en sortie diffère. Il suffit donc de la rendre éditable. Pour cela il est possible de définir des propriétés dans les Converters :

public class BooleanToValueConverter : IValueConverter 
{ 
   public object TrueValue { get; set; } 
   public object FalseValue { get; set; } 
   public object DefaultValue { get; set; } 
   private object GetValue(bool value) 
   { 
   return value ? TrueValue : FalseValue; 
   } 
   
   public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
   { 
   if (value == null) 
   return GetValue(false); 
   if (value is bool) 
   return GetValue((bool)value); 
   bool boolean; 
   
   // Install-Package CodeFluentRuntimeClient (http://www.softfluent.com/products/codefluent-runtime-client) 
   // Ou remplacer par Boolean.TryParse(string.Format("{0}", value), out boolean) 
   if (ConvertUtilities.TryChangeType(value, culture, out boolean)) 
   return GetValue(boolean); 
   var str = value as string; 
   if (str != null) 
   return GetValue(!string.IsNullOrEmpty(str)); 
   var enumerable = value as IEnumerable; 
   if (enumerable != null) 
   { 
   var enumerator = enumerable.GetEnumerator(); 
   bool any = enumerator.MoveNext(); 
   return GetValue(any); 
   } 
   // ... 
   return DefaultValue; 
   } 
}

On peut maintenant utiliser ce Converter dans différents cas :

<Application.Resources> 
   <system:Boolean x:Key="TrueValue">True</system:Boolean> 
   <system:Boolean x:Key="FalseValue">False</system:Boolean> 
   <utilities:BooleanToValueConverter 
   x:Key="ValueToBooleanConverter" 
   TrueValue="{StaticResource TrueValue}" 
   FalseValue="{StaticResource FalseValue}" 
   DefaultValue="{StaticResource FalseValue}" /> 
   <utilities:BooleanToValueConverter 
   x:Key="ReverseValueToBooleanConverter" 
   TrueValue="{StaticResource FalseValue}" 
   FalseValue="{StaticResource TrueValue}" 
   DefaultValue="{StaticResource TrueValue}" /> 
   <utilities:BooleanToValueConverter 
   x:Key="ValueToVisibilityConverter" 
   TrueValue="{x:Static Visibility.Visible}" 
   FalseValue="{x:Static Visibility.Collapsed}" 
   DefaultValue="{x:Static Visibility.Visible}" /> 
</Application.Resources>

Nous avons maintenant un seul Converter mais celui-ci n’est plus limité à un seul cas d’usage.

Le code complet : https://gist.github.com/meziantou/04ea08a9897755ba0b06

Ne ratez plus aucune actualité avec la newsletter mensuelle de SoftFluent

Newsletter SoftFluent