Localiser une enum

Lors d’un de mes développement Windows Phone, j’ai eu besoin de localiser mon enum qui était bindé à un ListPicker. Je vais donc vous expliquer comment j’ai procédé pour la localisation (Ce n’est pas le seul moyen de le faire, mais je trouve que c’est assez propre).

1. Mise en situation

2. Localiser son enum

 

Mise en situation

J’ai donc dans mon application une enum (AnimalType) qui est bindé directement à un ListPicker.

 public enum AnimalType     {         Dog,         Cat,         Duck,         Dolphin,         Elephant,         Other     }

J’ai donc mon binding dans mon viewmodel qui me retourne directement la liste des enums

 public Array Animals { get { return Enum.GetValues(typeof(AnimalType)); } }

Et dans ma vue, j’ai mon ListPicker avec le binding

 <toolkit:ListPicker ItemsSource="{Binding Animals}" >             toolkit:ListPicker>

Pour qu’on soit sur que l’application est localisé, on va forcer la culture fr-FR dans l’app.xaml.cs

 Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("fr-FR");

Et ensuite 2 fichiers de ressources dans notre application

Donc jusqu’ici rien de spécial, un binding classique. Sauf que j’aimerais que mon énumération soit traduite car mon application est en français et que les terms de mon énumération sont en anglais

Localiser son enum

Entrons donc dans le vif du sujet et voyons comment procéder. Nous allons en fait créer un attribut personnalisé que nous allons aller lire avec un converter et rechercher le term correspondant dans nos ressources pour pouvoir l’afficher. Commençons donc par notre attribut personnalisé :

 public class LocalizedEnumAttribute : DescriptionAttribute    {        public LocalizedEnumAttribute(string resourceID) : base(GetStringFromResource(resourceID)) { }        private static string GetStringFromResource(string resourceID)        {            // on va rechercher la ressource correspondant à notre ID            return AppResources.ResourceManager.GetString(resourceID);        }    }

On applique ensuite cet attribut sur les éléments de notre énumération en lui donnant un id qui correspondra au nom dans notre fichier de ressource (Pour créer le fichier de ressource, sélectionnez les langues que vous voulez supporter dans le fichier WMAppManifest et sauvez votre projet, il va créer les fichiers automatiquement 🙂 )

 public enum AnimalType {     [LocalizedEnum("Enum_Dog")]     Dog,     [LocalizedEnum("Enum_Cat")]     Cat,     [LocalizedEnum("Enum_Duck")]     Duck,     [LocalizedEnum("Enum_Dolphin")]     Dolphin,     [LocalizedEnum("Enum_Elephant")]     Elephant,     [LocalizedEnum("Enum_Other")]     Other }

Ensuite notre converter qui va nous servir à aller chercher la valeur de la ressource

 public class EnumToStringConverter : IValueConverter    {        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)        {            if (value != null)            {                Type type = value.GetType();                string name = Enum.GetName(type, value);                if (name != null)                {                    FieldInfo field = type.GetField(name);                    if (field != null)                    {                        DescriptionAttribute attr = System.Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute;                        if (attr != null)                            return attr.Description;                    }                }                return value.ToString();            }            return null;        }        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)        {            throw new NotImplementedException();        }    }

Je ne vais pas détailler le converter, mais en gros il va aller rechercher via réflection les attributs qu’il y’a sur l’élément qu’on lui a donné et récupérer la valeur de cet attribut ( qui correspond à notre traduction ) pour ensuite le retourner.

Notre ListPicker va donc ressembler à ceci avec notre converter sur les bindings

 <toolkit:ListPicker ItemsSource="{Binding Animals}" >                 <toolkit:ListPicker.FullModeItemTemplate>                     <DataTemplate>                         <Grid>                             <TextBlock Text="{Binding Converter={StaticResource EnumToStringConverter}}" />                         Grid>                     DataTemplate>                 toolkit:ListPicker.FullModeItemTemplate>                 <toolkit:ListPicker.ItemTemplate>                     <DataTemplate>                         <Grid>                             <TextBlock Text="{Binding Converter={StaticResource EnumToStringConverter}}" />                         Grid>                     DataTemplate>                 toolkit:ListPicker.ItemTemplate>             toolkit:ListPicker>

Et Tadam ! Notre application affiche maintenant nos traductions 🙂

 

No Comments

Post a Comment