Internationalisez votre application Windows Phone 7

Le Marketplace de Windows Phone 7 autorise une diffusion mondiale de l’application, mais aussi des diffusions spécifiques dans des marchés localisés. Par exemple vous pouvez avoir envie de diffuser une version Française de votre application sur les terminaux en langue française, et en Allemand sur les terminaux allemands. C’est ce qu’on appelle la localisation. De la même manière, certaines valeurs se représentent différemment d’un pays à l’autre : par exemple la date s’écrit au format mm/jj/aaaa dans les pays anglo-saxons mais jj/mm/aaaa dans les pays francophones. En utilisant les bons outils, on peut indiquer au téléphone d’adapter son affichage en fonction des options choisies par l’utilisateur. C’est ce qu’on appelle la globalisation. Localisation et globalisation forment les deux mamelles de l’internationalisation d’une application, et se servent de plusieurs notions qu’il faut connaitre :

La notion de culture se réfère à un ensemble de préférences (langage, monnaie, affichage des dates…) qu’on identifie par un code en deux parties : <langage>-<region>. Par exemple, en-us pour anglais-états-unis ou fr-fr pour français-France qui n’est pas la même chose que fr-ca (français-canada). Ce code peut aussi porter le nom de « Locale ».

Il y a 3 types de « culture » dans le framework : « invariant » qui désigne justement l’absence de culture choisie, «  neutral » qui représente un langage sans association à une région particulière (fr par exemple) et specific qui représente une culture associée à la fois à un langage et une région.

La classe CultureInfo nous permettra de récupérer les informations à propos de la culture comme celle qui a été paramétrée dans le système, le formatage des différents types de données (date, monnaie, etc) et jusqu’à un calendrier spécifique (et oui, le calendrier hébreu est différent du calendrier japonais !!)

La notion d’encodage, qui est un outil pour représenter les différents caractères utilisés par une langue de façon numérique : les plus connus sont ASCII, UTF-8, Unicode… Il est bon de savoir que Windows Phone 7 utilise l’Unicode. La classe Encoding vous aidera à vous abstraire des problèmes potentiels d’encodage (par exemple lors du téléchargement de données qui ne sont pas encodées en Unicode)

La globalisation et l’utilisation de la classe CultureInfo

La première (et peut-être la seule) chose à savoir est qu’il existe deux instances de la classe CultureInfo dont se sert votre application : il s’agit des propriétés CurrentCulture et CurrentUICulture de l’objet Thread.CurrentThread. Cela permet de savoir par exemple comment un objet de type DateTime sera affiché lors de l’appel à sa méthode ToString() . Pour choisir la façon d’afficher ces types de données d’une manière qui n’est pas celle choisie à l’échelle du système (dans le menu Settings du terminal Windows Phone 7) il suffit de créer une nouvelle instance de la classe CultureInfo en lui passant en paramètre la locale souhaitée (par exemple fr-FR) et assigner cette instance aux propriétés CurrentCulture et CurrentUICulture.

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

La localisation – bien répartir ses ressources pour supporter proprement différents langages

Comme par le passé avec le .NET Compact Framework, la première étape de la localisation consiste à utiliser des fichiers de ressources (extension .resx). On peut ajouter ces fichers avec dans le menu « Add -> Add New Item » en choisissant « Resource File ».

clip_image002

Attention, pour que le framework retrouve ses petits il faut adopter une stratégie de nommage particulière : d’abord un fichier de ressources par défaut qu’on nomme <NomDuFichierRessources>.resx  puis ensuite les fichiers de ressources localisées qu’on nommera de la façon suivante : <NomDuFichierRessources>.<Locale>.resx.

Je vous conseille de commencer par créer uniquement le fichier par défaut, y insérer toutes vos chaines de caractères, et ensuite seulement, une fois que toutes les ressources par défaut sont créées, copier/coller et renommer le fichier pour les différentes cultures à supporter, avant de changer le contenu des chaines de caractères : de cette manière vous êtes sûr que toutes les chaines de caractères localisées ont le même nom indépendamment de la culture…

Il faut ensuite définir la culture par défaut supportée par l’application (celle qui utiliser la fichier <NomDuFichierRessources>.resx). Pour cela dans l’explorateur de solution, cliquez sur le nom du projet et choisissez ses propriétés (Properties). Dans l’onglet Application, cliquez sur le bouton Assembly Information et dans la liste Neutral language choisissez la culture par défaut.

clip_image004

Dernière opération « manuelle » s’il en est, fermez votre projet et ouvrez le fichier .csproj dans un éditeur de texte : c’est fait un fichier xml. Trouvez le tag  <SupportedCultures> et ajoutez toutes les locales que votre application doit supporter (y compris la locale par défaut) dans ce tag, séparées par des points-virgules.

 <SupportedCultures>en-US;fr-FR;</SupportedCultures>

Il ne reste plus qu’à utiliser ces fichiers de ressources dans votre projet : là encore, il faut suivre quelques étapes : c’est un peu plus compliqué qu’avec le .NET Compact Framework car il faut que ces chaines de caractères localisées soient accessible à la fois depuis le code et le XAML sous forme de ressources.

D’abord, ouvrez chacun de vos fichiers ressources et dans la liste « Access Modifier » en haut de l’éditeur sélectionnez la valeur « Public ». Il faut le faire pour chacun des fichiers ressources.

clip_image006

Ensuite, il faut créer une nouvelle classe dans votre application (qu’on appellera comme on veut, j’utilise ici « LocalizedStrings » car c’est ce qui est suggéré par la documentation MSDN) dans laquelle on créera une propriété qui reverra vers ces fichiers de ressources fraichement créés : dans le bout de code suivant, LocalizedResources est le nom que j’ai choisi pour mon fichier de ressources, on retrouve donc une classe de ce type dans l’espace de nommage de mon application.

 public class LocalizedStrings
{
    public LocalizedStrings()
    { }

    private static LocalizedResources locTestResources = new LocalizedResources();
    public LocalizedResources LocTestResources { get { return locTestResources; } }
}

Après ça, il faut ouvrir le fichier App.xaml et dans la section « <Application.Resources> » il faut rajouter le bout de code suivant :

 <Application.Resources>
    <local:LocalizedStrings xmlns:local="clr-namespace:LocalizationTest" x:Key="LocalizedStrings" />
</Application.Resources>

Si votre projet dispose de plusieurs fichiers de localisation, il suffit de rajouter des propriétés dans la classe LocalizedStrings.

Enfin, il n’y a plus qu’à utiliser ces ressources dans le code XAML avec un simple Binding de la façon suivante :

 {Binding Path=LocTestResources.PageName, Source={StaticResource LocalizedStrings}}

Et dans le code C#, c’est d’une simplicité déconcertante : il suffit d’accéder à la classe LocalizedResources :

 PageTitle.Text = LocalizedResources.PageName;

Vous voilà maintenant en mesure de supporter plusieurs langages dans une même version de votre application, effort qui saura sans aucun doute séduire vos utilisateurs. Attention cependant à bien réfléchir à vos traductions !!