3

Je voudrais obtenir tout mon texte localisé à partir de ViewModels (car il est souvent dynamique), et je me demandais comment vous utiliseriez un convertisseur pour obtenir le texte des fichiers json utilisés pour la localisation . Par exemple, dans le code ci-dessous, je voudrais LocalisedString utiliser le convertisseur que j'utilise actuellement dans mes vues dans les fixations pour le texte statique -Localiser du texte dans MvvmCross ViewModels

public string MyText // used in the binding in the View 
{ 
    get 
    { 
     string exclamation; 

     if (MyValue <= 3.3) 
     { 
      exclamation = LocalisedString("Rubbish!"); 
     } 
     else if (OverallScore > 3.3 && OverallScore <= 6.6) 
     { 
      exclamation = LocalisedString("Good!"); 
     } 
     else 
     { 
      exclamation = LocalisedString("Excellent!"); 
     } 

     return exclamation; 
    } 
} 

Actuellement en utilisant la version 1 de MvvmCross.

Toute aide très appréciée.

Répondre

9

Remarque: cette réponse est à propos de vNext - il devrait être assez facile de revenir au maître ... Les différences dans la zone ne sont pas si grandes.


Il existe un mécanisme de localisation de texte intégré à MvvmCross.

Le seul échantillon public qui l'utilise est l'exemple de conférence.


Cet échantillon comprend partagé et ViewModel fichiers Json spécifiques - see

Ces Json fichiers contiennent chaque paire simples clé-valeur comme:

{ 
"Title":"SQLBits X", 
"Welcome":"Welcome", 
"Sessions":"Sessions", 
"Sponsors":"Sponsors", 
"Tweets":"Tweets", 
"Favorites":"Favorites" 
} 

Ils sont liés pour Droid, Touch et WP en tant que contenu ou assets ... tous accessibles par la plateforme en utilisant le plugin ResourceLoader.


Pour utiliser ces fichiers JSON lors de l'exécution, le projet de base les charge dans le TextProviderBuilder:

protected override IDictionary<string, string> ResourceFiles 
    { 
     get 
     { 
      var dictionary = this.GetType() 
       .Assembly 
       .GetTypes() 
       .Where(t => t.Name.EndsWith("ViewModel")) 
       .Where(t => !t.Name.StartsWith("Base")) 
       .ToDictionary(t => t.Name, t => t.Name); 

      dictionary[Constants.Shared] = Constants.Shared; 
      return dictionary; 
     } 
    } 

Vous pouvez évidemment facilement charger d'autres fichiers JSON ici si vous voulez. Il est pas rare que certains de mes applications pour avoir:

  • un fichier pour les erreurs
  • un fichier pour les états Partagés généraux
  • un fichier pour les composants spécifiques
  • un fichier par ViewModel

Alors que d'autres ont:

  • juste un gros fichier!

L'internationalisation - quand c'est fait - est faite en chargeant un ensemble différent de fichiers JSON. En règle générale, vous chargez le jeu par défaut en premier, puis vous chargez les remplacements incrémentiels. Ainsi, vous pouvez charger l'anglais par défaut, Cat en tant que remplacement et Cat-Lol en tant que raffinement supplémentaire.

Pour des discussions sur ce voir:


En supposant que vous avez un fichier partagé et un fichier par ViewModel, puis fournir un accès à l'exécution aux valeurs de texte à partir du JSON, le BaseViewModel présente 2 propriétés:

public IMvxLanguageBinder TextSource 
    { 
     get { return new MvxLanguageBinder(Constants.GeneralNamespace, GetType().Name); } 
    } 

    public IMvxLanguageBinder SharedTextSource 
    { 
     get { return new MvxLanguageBinder(Constants.GeneralNamespace, Constants.Shared); } 
    } 

Ces propriétés sont utilisées dans la liaison de données en utilisant:

  • Chemin spécifiant l'utilisation de SharedTextSource ou TexteSource
  • MvxLanguageBinderConverter que le convertisseur
  • la clé de texte comme ConverterParameter

Par exemple, dans Droid, c'est:

<TextView 
    style="@style/AboutPageBodyText" 
    local:MvxBind="{'Text':{'Path':'TextSource','Converter':'Language','ConverterParameter':'Title'}}" 
    /> 

Bien que moderne « suisse » liaison ce serait écrit que:

<TextView 
    style="@style/AboutPageBodyText" 
    local:MvxBind="Text TextSource, Converter=Language, ConverterParameter='Title'" 
    /> 

Tout code qui souhaite utiliser le texte peut aussi le faire - voir par exemple comment le texte de TimeAgo est créé à partir des chaînes de ressources en TimeAgoConverter.cs qui utilise des chaînes de ressources comme:

{ 
"TimeAgo.JustNow":"just now", 
"TimeAgo.SecondsAgo":"{0}s ago", 
"TimeAgo.MinutesAgo":"{0}m ago", 
"TimeAgo.HoursAgo":"{0}h ago", 
"TimeAgo.DaysAgo":"{0}d ago", 
"TimeAgo.Never":"never" 
} 

Le code pour cela est efficace:

var valueToFormat = 42; 
var whichFormat = "TimeAgo.DaysAgo"; 

var textProvider = this.GetService<IMvxTextProvider>(); 
var format = textProvider.GetText(Constants.GeneralNamespace, Constants.Shared, whichFormat); 

return string.Format(format, valueToFormat) 

Le langage liant et les ValueConverter sont vraiment très simple Code

Alors ne hésitez pas à construire quelque chose de plus sophistiqué pour votre application si vous en avez besoin.


D'autres techniques de localisation texte multi-plateforme sont disponibles - je me voudrais particulièrement essayer vernaculaires une journée - https://github.com/rdio/vernacular

+1

juste en ajoutant un autre sujet lié - http: // stackoverflow.com/questions/13471994/mvvmcross-localization-get-text-from-dynamic-value – Stuart

+0

Un grand merci pour cela - j'essaierai au cours des prochains jours de le trier - je reviendrai avec mes résultats. – SomaMan

+0

Grand - Je l'ai tout travail bien maintenant, comme vous le dites, assez simple à la fin – SomaMan

0

Peut-être que vous devriez retourner des énumérations au lieu de chaînes et gérer la localisation dans les vues.

+0

Parce qu'il est une application multi-plateforme (iPhone, Android et Windows), nous essayons pour éviter de faire trop dans les Vues – SomaMan

+0

Va devoir être d'accord pour ne pas être d'accord. À mon avis, la localisation est strictement un problème de vue car chaque plate-forme gère différemment et a des directives différentes pour chacun. La manipulation au niveau ViewModel lie votre View à votre ViewModel, ce qui est le problème que MVVM essaie d'éviter. –

+1

Je supposais que la liaison à partir des propriétés de View to VM vous lie en quelque sorte ... – SomaMan