我想从ViewModel获取我的所有本地化文本(因为它通常是动态的),我想知道如何使用转换器从用于本地化的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版。
任何帮助都非常感激。
答案 0 :(得分:9)
注意:这个答案是关于vNext的 - 它应该很容易移植回主人......区域的差异并不大。
MvvmCross内置了一个文本本地化机制。
使用它的唯一公共样本是会议样本。
此示例包含特定于共享和ViewModel的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作为进一步细化。
有关此问题的一些讨论,请参阅:
假设每个ViewModel有一个共享文件和一个文件,那么为了提供对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); }
}
这些属性用于数据绑定:
例如,在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'"
/>
任何希望使用Text的代码也可以这样做 - 例如,参见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是非常简单的代码
如果您需要,可以随意为您的应用构建更复杂的内容。
其他跨平台的文本本地化技术可用 - 我自己特别想有一天尝试白话 - https://github.com/rdio/vernacular
答案 1 :(得分:0)
也许您应该返回枚举而不是字符串并处理视图中的本地化。