3

我想從ViewModels獲取所有本地化文本(因爲它通常是動態的),我想知道如何使用轉換器從用於本地化的json文件中獲取文本。例如,在下面的代碼,我想LocalisedString使用我目前在綁定靜態文本在視圖中使用轉換器 -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; 
    } 
} 

目前使用MvvmCross的版本1。

任何幫助非常感謝。

回答

9

注意:這個答案是關於vNext - 它應該是相當容易回到主人......在這方面的差異並不大。


在MvvmCross中內置了文本本地化機制。

使用它的唯一公共樣本是會議樣本。


此示例包括共享和視圖模型特定JSON檔案 - see

這些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文件。它的情況並不少見一些我的應用程序有:

  • 錯誤
  • 一般共享報表
  • 特定組件
  • 每視圖模型
文件的文件的文件的文件

雖然其他人有:

  • 只是一個大文件!

國際化 - 完成後 - 通過加載一組不同的JSON文件完成。通常情況下,您首先加載默認設置,然後加載增量覆蓋 - 這樣您可以將默認加載英語,將Cat用作覆蓋,將Cat-Lol加載爲默認設置。

有關此看到一些討論:


假設你有一個共享的文件和每個視圖模型一個文件,然後提供對來自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'" 
    /> 

其希望使用的文字也能做到這一點的任何代碼 - 例如見TIMEAGO文本如何從資源字符串創建在TimeAgoConverter.cs它使用的資源字符串,如:

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

語言粘合劑和ValueConverter真的是非常簡單的代碼

可以隨意打造一些更復雜了您的應用程序,如果你需要它。


其他跨平臺的文本定位技術可供選擇 - 我自己特別想嘗試白話第一天 - https://github.com/rdio/vernacular

+1

只是添加另一個鏈接的主題 - http:// stackoverflow。com/questions/13471994/mvvmcross-localization-get-text-from-dynamic-value – Stuart 2013-02-14 18:17:06

+0

非常感謝這個 - 我將在接下來的幾天裏對它進行整理 - 我會回顧我的結果。 – SomaMan 2013-02-15 08:23:29

+0

太好了 - 我已經很好地工作了,正如你所說的,最後很簡單 – SomaMan 2013-02-22 12:04:09

0

也許你應該返回枚舉而不是字符串,並處理視圖中的本地化。

+0

因爲它是一個跨平臺的應用程序(iPhone,Android和贏)我們正在努力避免在視圖中做太多 – SomaMan 2013-02-14 17:46:45

+0

必須同意不同意。在我看來,本地化嚴格來說是一個View問題,因爲每個平臺都有不同的處理方式,並且對每個平臺都有不同的指導。在ViewModel級別處理它會將View與ViewModel綁定,這是MVVM試圖避免的問題。 – 2013-02-14 23:32:38

+1

我假設從視圖綁定到虛擬機屬性有點類似於你... – SomaMan 2013-02-22 12:03:21