Gestion des Resources dans un projet PCL pour Xamarin Forms et UWP

Pour gérer le multi-langue dans vos applications, il vous faut passer par la gestion des resources qui peut s’avérer vite complexe et pas vraiment pratique dans certaines conditions.

Dans mon cas, j’ai une application UWP existante avec les ViewModels, les resources, … dans un seul et unique projet. Le but, ici, est de s’étendre sur les autres plateformes, Android et iOS via Xamarin, tout en conservant l’existant de l’UWP (pour la gestion des vues en XAML). Notre choix pour réaliser se portage a été de le réaliser en Xamarin.Forms avec un projet en PCL (Portable Class Library) pour la gestion de nos ViewModels, ainsi que tous les éléments réutilisables dans chacun de nos projets UWP / xamarin Forms. Cela nous a amené à l’intégration des resources pour les textes de l’application dans le projet PCL.

Les resources en UWP sont au format « resw » et doivent être transformées en « resx » pour être intégrer à une PCL. Rien de compliqué ici, copiez les lignes de votre fichier « resw », puis collez les dans le fichier de la PCL. Néanmoins, il vous faudra supprimer toutes les références à la vue, c’est à dire les « .Text » ou « .Content » de vos clés.

Exemple d’un fichier .resw:

Ce qui nous donne en .resx:

En UWP, pour utiliser une resource en « resw », il faut simplement renseigner le Uid de l’élément avec la resource correspondant, et il va automatiquement mettre la resource dans le champ indiqué.

<TextBlock x:Uid="TextBlockMessageNetworkInfo"/>

Cependant cette méthode ne fonctionne pas pour le fichier « resx ».

Comment gérer le format Resx pour votre projet Xamarin.Forms ?

Pour gérer l’affichage de vos resources, vous avez plusieurs solutions que vous pouvez mettre en place.

La premier, classique, est de renseigner en code behind la resource à votre élément, comme ceci:

myLabel.Text = AppResources.TextBlockMessageNetworkInfo;

Pour plus d’information, je vous conseille de lire la doc de Xamarin : ici

La deuxième solution est de faire un peu comme pour les fichiers Resw en UWP, c’est à dire d’écrire directement dans le XAML.

Voici la classe à rajouter dans votre projet Xamarin.Forms:

Cette classe implémente l’interface  IMarkupExtension qui permet de définir des extensions de balise pour le XAML de Xamarin.Forms. Cette interface vous fait implémenter la méthode  ProvideValue , le point d’entrée de la classe.

Il ne vous reste plus qu’à aller chercher votre texte en fonction de la key passée dans la propriété  Text de votre classe.

Exemple simple avec uniquement un fichier resource :

<Label Text="{resources:ResourceExtension Key}" />

Néanmoins, si vous avez plusieurs fichiers resources (comme dans mon projet), vous pouvez utiliser la classe ci-dessus, en rajoutant dans le switch vos différents fichiers de resource.

Pour l’utilisation de cette classe, ajoutez dans le haut de votre XAML de la page son namespace :

xmlns:resources="clr-namespace:FeedLab.Forms.Strings"

puis par exemple, pour un Label dans la propriété Text , renseignez le fichier de la resource puis sa clef, comme ceci :

<Label Text="{resources:ResourceExtension CommonResources.Key}" />

La classe cherchera la resource dans le fichier spécifié et l’affichera dans votre champ.

Et comment ça se passe pour UWP ?

Maintenant, il ne reste plus cas gérer ces fichiers Resx pour le projet UWP. Dans le principe, c’est la même méthode que pour Xamarin.Forms mais avec un petit ajout.

On retrouve notre classe pour le chargement :

Dans votre app.xaml.cs, rajouter dans le constructeur la ligne :

Cela permet de customiser le XAML loader.

Et il ne vous reste plus qu’à renseigner dans votre XAML la resource dans la propriété souhaitée :

Voila, maintenant plus d’excuse pour ne pas rendre vos applications multi-langues 😉