你的位置:首页 > ASP.net教程

[ASP.net教程]“Win10 UWP 开发系列”之多语言支持


 

Win10的SDK正式版已经发布了,"UAP"的名称改成了"UWP",微软改名部好忙啊。随便他了。今天想试试正式版的SDK,升级一下Currency Exchanger,在处理多语言的时候,发现Multilingual App Toolkit 3.0已经不能用在VS2015里了,需要更新。因此把这部分单独再说一下。

 

一、安装多语言工具包

 

VS2015需要安装最新的Multilingual App Toolkit 4.0 beta,下载地址:https://visualstudiogallery.msdn.microsoft.com/6dab9154-a7e1-46e4-bbfa-18b5e81df520?SRC=VSIDE

也可以在VS2015的扩展和更新里安装,注意要安装4.0版本的,不然不能在VS2015里用:

我还是习惯使用MVVM-Sidekick框架来做,VS扩展插件也可以在VS2015的扩展和更新里安装:

 

二、新建项目

 

新建一个Win10的UWP项目,基于MVVM-Sidekick模板:

新建项目后,需要编译一下,Nuget会自动添加所需引用:

为了国际范,可以把默认语言改为英语。打开Package.appxmanifest,修改默认语言为en-US:

 

三、启用多语言支持

 

安装多语言工具包后在工具菜单点击Multilingual App Toolkit,启用多语言支持:

此时貌似什么也没发生,然后我又使劲用力多点了好几次,仍然没有任何反应。因为底下会报错:

提示没有找到本地资源文件。这就是4.0与旧版本的不同之处,之前启用多语言支持后会自动添加资源文件,但4.0必须手动添加了。

在项目中添加一个文件夹命名为Strings,在其中添加一个默认语言的文件夹,如果默认语言设置为en-US,则添加的文件名也为en-US,然后再添加一个资源文件,文件名为Resources.resw:

然后再启用多语言支持,就可以了:

 

四、添加多语言

右键单击项目,添加语言:

添加几种语言,比如中文简体和繁体:

多语言工具包会添加一个名为MultilingualResources的文件夹,里面添加了两个文件:

这就是对应语言的翻译文件,其实是一个

 

五、添加字符串并翻译

打开默认语言的资源,如en-US目录下的Resources.resw,添加几个资源:

注意,AppName.Text命名是这样的,如果有一个TextBlock控件要显示应用名称,那此控件的x:Uid属性要设置为AppName,这样就可以找到其Text值从而显示对应语言的应用名称。同样的,可以添加一个AppName.Width来区分不同语言下的控件宽度。

重新编译一下项目。

打开MultilingualResources文件夹里的xlf文件进行翻译:

可以点击这个按钮自动调用bing进行翻译:

翻译完后不要忘记保存。

然后重新编译项目,多语言工具包会自动填充每种语言的Resources.resw文件:

六、在页面中使用多语言

下面该画界面了。在页面中找到pageTitle控件,添加一个属性:

x:Uid="AppName"

把Text="{Binding Title}"删掉,现在是这样子:

然后运行一下试试:

虽然默认语言设置的是en-US,但因为本地计算机是使用的zh-CN,所以已经调用了中文的字符来显示。

现在部署到手机上试试。注意要将生成x86改成ARM。

手机上必须先添加英文和中文繁体语言包。把手机切换到en-US语言,运行一下:

已经根据设置的语言改变了。

 

七、在代码中使用多语言

除了在XAML页面中直接设置x:Uid属性,还可以在后台代码中使用多语言资源。我在之前一篇blog里介绍了自己实现类似WP8中AppResources的方式,经过某位高手指点,加上Cache后会提高性能,因此进行了一点改进。

添加一个AppResources.cs文件,输入以下代码:

public static class AppResources{private static ResourceLoader CurrentResourceLoader{get{return loader ?? (loader = ResourceLoader.GetForCurrentView());}}private static ResourceLoader loader; private static Dictionary<string, string> ResourceCache = new Dictionary<string, string>(); public static string GetString(string key){string result;if (ResourceCache.TryGetValue(key, out result)){return result;}result = CurrentResourceLoader.GetString(key);ResourceCache[key] = result;return result; } public static string Introduction{get{return GetString("Introduction");}}}

 

打开MainPage_Model.cs,使用propvm添加一个属性:

public string Introduction{get { return _IntroductionLocator(this).Value; }set { _IntroductionLocator(this).SetValueAndTryNotify(value); }}#region Property string Introduction Setupprotected Property<string> _Introduction = new Property<string> { LocatorFunc = _IntroductionLocator };static Func<BindableBase, ValueContainer<string>> _IntroductionLocator = RegisterContainerLocator<string>("Introduction", model => model.Initialize("Introduction", ref model._Introduction, ref _IntroductionLocator, _IntroductionDefaultValueFactory));static Func<string> _IntroductionDefaultValueFactory = () => default(string);#endregion

 

在vm的构造函数中赋值:

public MainPage_Model(){Introduction = AppResources.Introduction;}

 

在MainPage.xaml中添加一个TextBlock:

<TextBlock Grid.Row="2" Text="{Binding Introduction}" />

将Text属性绑定到VM的属性上。

然后运行:

英文设置下:

这样在后台代码中也可以用了。其实在代码中也可以直接使用AppResources.GetString("Introduction"),封装一下只是为了防止写错。