This article has been localized into French by the community.
Conversion de valeur avec IValueConverter
Jusqu'à maintenant nous avons utilisé quelques data bindings simples où la propriété source était toujours compatible avec la propriété de destination. Cependant vous allez rapidement tomber sur des cas où vous voulez utiliser une valeur d'un type dans un binding et la présenter de manière légèrement différente.
Quand utiliser un convertisseur de valeur
Les convertisseurs de valeurs sont fréquemment utilisés avec les data binding. Voici quelques exemples basiques :
- Vous avez une valeur numérique mais vous voulez afficher les valeurs égales à zéro d'une manière et les valeurs positives d'une autre manière
- Vous voulez cocher une CheckBox en fonction d'une valeur, mais cette valeur est une chaine de caractère du style "yes" ou "no" à la place d'une valeur booléenne
- Vous avez une taille de fichier en octets mais vous voulez l'afficher en octets, kilooctets, megaoctets ou gigaoctets en fonction de l'ordre de grandeur de la valeur
Ce sont quelques exemples simples, mais il y en a beaucoup d'autres. Par exemple, vous pourriez vouloir vérifier si une CheckBox est cochée sur base d'un booléen, mais vous voulez que l'état soit inversé, donc que la CheckBox soit cochée si la valeur est false et décochée si la valeur est true. Vous pouvez même utiliser un convertisseur pour générer une image pour une ImageSource, sur base de la valeur, comme par exemple un symbole vert pour true ou un symbole rouge pour false. Les possibilités sont quasiment infinies !
Pour ce genre de cas, vous pouvez utiliser un convertisseur de valeur. Ces petites classes, qui implémentent l'interface IValueConverter, vont agir comme un intermédiaire et vont traduire une valeur entre la source et la destination. Donc dans ces situations où vous avez besoin qu'une valeur soit transformée avant qu'elle n'atteigne sa destination ou qu'elle ne soit renvoyée à sa source, vous aurez très probablement besoin d'utiliser un convertisseur.
Implémentation d'un convertisseur de valeur simple
Comme nous l'avons dit, un convertisseur de valeur en WPF a besoin d'implémenter l'interface IValueConverter, ou bien l'interface IMultiValueConverter (celle-ci sera expliquée plus en détails plus tard). Les deux interfaces requièrent juste d'implémenter deux méthodes : Convert() et ConvertBack(). Comme leur nom le suggère, ces méthodes sont utilisées pour convertir une valeur au format de la destination et ensuite pour faire le chemin inverse.
Implémentons un convertisseur simple qui prend une chaine de caractère en entrée et qui retourne une valeur booléenne (et inversement). Si WPF est nouveau pour vous, ce qui est probablement le cas étant donné que vous lisez ce tutoriel, alors vous pourriez ne pas connaitre tous les concepts utilisés dans l'exemple. Mais ne vous inquiétez pas, ils seront tous expliqués après les extraits de codes :
<Window x:Class="WpfTutorialSamples.DataBinding.ConverterSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfTutorialSamples.DataBinding"
Title="ConverterSample" Height="140" Width="250">
<Window.Resources>
<local:YesNoToBooleanConverter x:Key="YesNoToBooleanConverter" />
</Window.Resources>
<StackPanel Margin="10">
<TextBox Name="txtValue" />
<WrapPanel Margin="0,10">
<TextBlock Text="Current value is: " />
<TextBlock Text="{Binding ElementName=txtValue, Path=Text, Converter={StaticResource YesNoToBooleanConverter}}"></TextBlock>
</WrapPanel>
<CheckBox IsChecked="{Binding ElementName=txtValue, Path=Text, Converter={StaticResource YesNoToBooleanConverter}}" Content="Yes" />
</StackPanel>
</Window>
using System;
using System.Windows;
using System.Windows.Data;
namespace WpfTutorialSamples.DataBinding
{
public partial class ConverterSample : Window
{
public ConverterSample()
{
InitializeComponent();
}
}
public class YesNoToBooleanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
switch(value.ToString().ToLower())
{
case "yes":
case "oui":
return true;
case "no":
case "non":
return false;
}
return false;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if(value is bool)
{
if((bool)value == true)
return "yes";
else
return "no";
}
return "no";
}
}
}
Code-behind
Revenons en arrière et traçons notre chemin à travers l'exemple. Nous avons implémenté un convertisseur dans le ficher de Code-behing appelé YesNoToBooleanConverter. Comme annoncé, elle implémente juste les deux méthodes requises, applées Convert() et ConvertBack(). La méthode Convert() part du principe qu'elle reçoit une chaine de caractères en entrée (le paramètre value) et la converti ensuite en une valeur booléenne true ou false, avec une valeur de repli égale à false. Pour le fun, j'ai ajouté la possibilité de faire cette conversion aussi depuis des mots en français.
La méthode ConvertBack() fait évidemment l'inverse. Elle attend une valeur de type booléen en entrée et retourne ensuite les mots en anglais "yes" ou "no", avec une valeur de repli égale à "no".
Vous pourriez vous demander qu'est-ce qu'il en est des autres paramètres que prennent ces deux méthodes, mais ils ne sont pas utiles dans notre exemple. Nous les utiliserons dans un des prochains chapitres où ils seront expliqués.
XAML
Dans la partie XAML du programme, nous commençons par déclarer une instance de notre convertisseur comme une ressource de la fenêtre. Nous avons ensuite une TextBox, deux TextBlocks et une CheckBox, et nous utilisons la propriété Converter avec une référence à notre propre convertisseur. Nous jonglons entre des valeurs de type chaine de caractère ou booléennes en fonction de ce dont nous avons besoin.
Si vous essayez d'exécuter cet exemple, vous aurez la possibilité de modifier la valeur à deux endroits. En écrivant "yes" dans la TextBox (ou n'importe quelle autre valeur si vous voulez obtenir false) ou en cochant la CheckBox. Peu importe ce que vous faites, la modification se reflétera sur l'autre contrôle ainsi que dans le TextBlock.
Résumé
C'était un exemple d'un convertisseur simple, rendu un peu plus long que nécessaire à des fins de démonstration. Dans le chapitre suivant, nous nous pencherons sur un exemple plus avancé. Mais avant que vous ne partiez et n'écriviez votre propre convertisseur, vous auriez intérêt à vérifier s'il n'en existe pas déjà un dans WPF prévu cet usage. Au moment de l'écriture de cet article, il existe plus de 20 convertisseurs intégrés dont vous pourriez tirer parti, mais vous devez connaitre leur nom. J'ai trouvé la liste suivante qui pourrait devenir très pratique pour vous : http://stackoverflow.com/questions/505397/built-in-wpf-ivalueconverters