3

ローカライズされたすべてのテキストをViewModelsから取得したいのですが(動的であることが多いため)、ローカリゼーションに使用されるjsonファイルからテキストを取得するためにコンバーターをどのように使用するのか疑問に思いました。たとえば、以下のコードでは、LocalisedStringで、静的テキストのバインディングのビューで現在使用しているコンバーターを使用したいと思います-

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;
    }
}

現在、MvvmCrossのバージョン1を使用しています。

どんな助けでも大歓迎です。

4

2 に答える 2

9

注:この回答はvNextに関するものです。マスターに移植するのはかなり簡単なはずです...この領域の違いはそれほど大きくありません。


MvvmCrossにはテキストローカリゼーションメカニズムが組み込まれています。

これを使用する唯一の公開サンプルは、会議サンプルです。


このサンプルには、共有およびViewModel固有のJsonファイルが含まれています-を参照してください

これらのJsonファイルにはそれぞれ、次のような単純なキーと値のペアが含まれています。

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

これらは、コンテンツまたはアセットとしてDroid、Touch、およびWPにリンクされています...すべて、ResourceLoaderプラグインを使用してプラットフォームからアクセスされます。


実行時にこれらのJSONファイルを使用するために、コアプロジェクトはそれらを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;
        }
    }

必要に応じて、他のJSONファイルをここに簡単にロードできます。一部のアプリに次の機能があることは珍しくありません。

  • エラーのファイル
  • 一般的な共有ステートメントのファイル
  • 特定のコンポーネントのファイル
  • ViewModelごとのファイル

他の人が持っている間:

  • たった1つの大きなファイル!

国際化(実行される場合)は、別のJSONファイルのセットをロードすることによって実行されます。通常は、最初にデフォルトセットをロードしてから、増分オーバーライドをロードします。したがって、デフォルトとして英語、オーバーライドとしてCat、さらに改良されたCat-Lolをロードする場合があります。

これに関するいくつかの議論については、以下を参照してください。


ViewModelごとに1つの共有ファイルと1つのファイルがあるとすると、JSONからのテキスト値へのランタイムアクセスを提供するために、BaseViewModelは2つのプロパティを提供します。

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

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

これらのプロパティは、以下を使用したデータバインディングで使用されます。

  • SharedTextSourceとTextSourceのどちらを使用するかを指定するパス
  • コンバーターとしてのMvxLanguageBinderConverter
  • ConverterParameterとしてのテキストキー

たとえば、Droidではこれは次のとおりです。

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

現代の「スイス」バインディングでは、これは次のように記述されます。

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

テキストを使用したいコードでもそれを行うことができます。たとえば、TimeAgoConverter.csのリソース文字列からTimeAgoテキストが作成される方法を参照してください これは次のようなリソース文字列を使用します。

{
"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"
}

このためのコードは事実上次のとおりです。

 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)

言語BinderとValueConverterは本当に非常に単純なコードです

したがって、必要に応じて、アプリ用にさらに洗練されたものを自由に作成してください。


他のクロスプラットフォームのテキストローカリゼーション手法が利用可能です-私自身、特にいつかVernacularを試してみたいです-https ://github.com/rdio/vernacular

于 2013-02-14T18:08:32.157 に答える
0

おそらく、文字列の代わりに列挙型を返し、ビューでローカリゼーションを処理する必要があります。

于 2013-02-14T17:17:33.903 に答える