Après une expérience de conversions tout à fait improbable (sur 4 couches applicatives!!!) sur un projet en Debug, il va être bon de rappeller les fondemmentaux :
a - Conversion monétaire
Allez on assume que les prix sont stockés dans notre base en Euros sous un format decimal !
Alors on va créer notre converter :
Using ... namespace MyConverterApp { [System.Windows.Data.ValueConversion(typeof(decimal), typeof(string))] class ConvertMoneyInEuros : System.Windows.Data.IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo cultureInfo) { decimal myPrice = decimal.Parse(value.ToString()); return myPrice.ToString("C"); } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo cultureInfo) { string aMyPrice = value.ToString(); decimal result; if(decimal.TryParse(aMyPrice, System.GLobalization.NumberStyles.Any, null, out result) { return result; } else return 0; } } }
Ensuite on instancie dans le XAML :
<Window x:Class="MyConverterApp" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:MyConverterApp" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <local:ConvertMoneyInEuros x:Key="DisplayInEuros"/> </Window.Resources> ... <Window>
Puis il ne nous reste plus qu'à l'utiliser dans notre Elément d'interface (en supposant un DataContext dans la Grid) :
<Grid Name="Grid1"> <StackPanel> <label Content={Binding Path=UnitPrice, Converter={StaticResource DisplayInEuros}} </StackPanel>
Et cela nous affiche un joli 12,50 € !
Supposons maintenant que nous souhaitions l'afficher en dollars US mais pas comme font certains, qu'un produit à $6.00 ne devienne pas un produit vendu à 6,00 €... Mais bien que notre "12,50 €" devienne un "$9.52" Alors on créé simplement un nouveau converter :
Using ... namespace MyConverterApp { [System.Windows.Data.ValueConversion(typeof(decimal), typeof(string))] class ConvertMoneyInUSDollars : System.Windows.Data.IValueConverter { readonly decimal _rate = decimal.Parse("1,3131"); readonly System.Globalization.CultureInfo _usCulture = new System.Globalization.CultureInfo("en-US"); readonly System.Globalization.CultureInfo _currentcult = System.Globalization.CultureInfo.CurrentCulture; public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo cultureInfo) { decimal myPrice = decimal.Parse(value.ToString()); myPrice = myPrice /_rate return myPrice.ToString("C", _usCulture); } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo cultureInfo) { string aMyPrice = value.ToString(); decimal result; if(decimal.TryParse(aMyPrice, System.GLobalization.NumberStyles.Any, null, out result) { result = result * _rate; return result; } else return 0; } } }
Supposons maintenant souhaite basculer dynamiquement dans le code d'un affichage en Euros à un affichage en Dollars US avec un bouton radio par exemple :
private void RadioButtonEURClick(object sender, RoutedEventArgs e) { var bd = new Binding(); bd.Converter = new ConvertMoneyInEuros(); bd.Path = new PropertyPath("UnitPrice"); bd.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged; bd.Mode = BindingMode.TwoWay; MyDynamicTextBox.SetBinding(TextBox.TextProperty, bd); } private void RadioButtonUSDClick(object sender, RoutedEventArgs e) { var bd = new Binding(); bd.Converter = new ConvertMoneyInUsDollars(); bd.Path = new PropertyPath("UnitPrice"); bd.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged; bd.Mode = BindingMode.TwoWay; MyDynamicTextBox.SetBinding(TextBox.TextProperty, bd); }
b - Conversion d'image
Les exemples présentés ici sont uniquement pour illustrer à nouveau les principes des converters à vous de les réadapter.
Voilà un converter pour remplacer le chemin d'accès à une image en image :
Using ... namespace MyConverterApp { [System.Windows.Data.ValueConversion(typeof(string), typeof(BitmapImage))] class ConvertStringToBitmap : System.Windows.Data.IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo cultureInfo) { try { string myPath = (string)value; Uri myUri = new Uri(myPath); BitmapImage myImage = new BitmapImage(myUri); return myImage; } catch { return new BitmapImage(new Uri("C:\\ImageNotAvailable.jpg")); } } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo cultureInfo) { throw new NotImplementedException(); } } }Pour résumer, les converters sont un moyens efficaces d'effectuer diverses convertions au niveau de l'IHM.
Bien, meme si mettre de l'intelligence dans un converter peut allourdir les perfs (surtout pour le second exemple).
RépondreSupprimerGood job
Merci, Julien !
SupprimerEffectivement les converters sont à utiliser avec parcimonie, et le deuxième avait surtout pour but de démontrer le principe. ;) Je suis bien heureux d'avoir enfin un commentaire !