上面几个小节通过示例介绍了如何引用资源以及设置应用语言来显示不同语言的信息,这些示例都只是添加了简体中文和英语两种语言来显示资源,而在一些复杂的应用程序中,字符串资源可能会被定义成多种语言,文件资源也可能为了根据不同的环境显示不同的效果而在程序中存储多种版本,这时应用程序就需要根据使用情况选取最匹配的资源作为应用的首选资源,本小节将通过示例模拟应用选取匹配资源的过程。

1.匹配规则

在应用程序运行时,应用对资源的选取受许多方面的因素的影响,例如系统的语言、屏幕的大小、分辨率和对比度等。应用程序的资源管理系统将根据应用的上下文环境对资源候选项进行排序,选取最匹配的候选项作为应用的首选资源。

例如应用选取的资源类型为字符串资源,资源的值通过五种语言来表示,这五种语言分别为英语(英国)、英语(美国)、法语(法国)、法语(加拿大)和简体中文(中国),这五种语言所对应的语言标识符分别为:en-GB、en-US、fr-FR、fr-CA和zh-CN。

在应用中添加一个ComboBox下拉列表框控件,分别将上面介绍的五种语言加入到列表框当中,用户可以通过此列表框在应用中选取任意一种语言来作为应用的首选语言。当用户选定一种语言作为应用的首选语言后。程序可以通过应用的资源管理器根据用户选择语言的标识符和系统的语言首选项标识符对所提供的资源候选项进行匹配并排序,从中选出最适合的资源。

资源管理器的匹配规则会首先判断应用程序当前的首选语言标识符的前缀,对所有的资源候选项进行匹配,从中选择前缀相同的资源候选项进行优先考虑,如果前缀相同再使用语言标识符的后缀对前缀匹配的资源候选项进行区分和排序。下面再在所有的资源候选项当中查找与当前系统的语言首选项相匹配的资源候选项进行排序,匹配的规则与应用的首选语言标识符匹配规则一样,先匹配资源候选项的前缀再匹配资源候选项的后缀,如果资源候选项的语言标识符从前缀就开始无法与当前的应用及系统语言匹配则代表此资源候选项完全不匹配,按此规则最后形成一个从高到底的资源候选项匹配序列。

下面假设系统的语言首选项为中文(简体),资源候选项为之前所介绍的五种语言,那么对于选取应用首选语言为“英语(英国)”的应用而言,通过规则匹配将得到以下顺序的资源候选项匹配序列:英语(英国)、英语(美国)、简体中文(中国)、法语(法国)和法语(加拿大)。

原因是,英语(英国)资源候选项的标识符是en-GB,它和当前应用所设置的首选语言在语言及区域两个前后缀上完全匹配,所以被排在了第一位,英语(美国)资源候选项的标识符是en-US与当前应用首选语言在语言上匹配但是在区域上不匹配,所以被排在了第二位。接下来由于系统的语言首选项为中文(简体),所以简体中文(中国)资源候选项从系统的语言首选项角度来说也是匹配的,但是却在这五种资源候选项当中排第三位,这是由于系统级别的语言首选项的优先级别要低于应用程序本身所设置的首选语言,而排列末尾的“法语(法国)”和“法语(加拿大)”的标识符前缀为fr,它们与英语(英国)所代表的en-GB语言标识符从前缀比较上就已经不相同,所以表示法语的两种语言是完全不匹配的。下面通过代码演示上述过程。

2.匹配示例

新建一个Windows应用商店的空白应用程序项目,并命名为SelectMatchResources。在项目中新建一个名为“Strings”的文件夹,在“Strings”文件夹下新建一个名为“dimensions”的子文件夹,在“dimensions”文件夹中添加5个资源文件并在资源文件中添加资源值,最终的资源文件名及其中的资源值,如表18-1所示。

表18-1 dimensions文件夹下的5个资源文件及资源文件中的资源

资源文件名

资源名称

资源值

dimensions.lang-en-GB

LanguageOnly

英语资源(英国)

dimensions.lang-en-US

LanguageOnly

英语资源(美国)

dimensions.lang-fr-FR

LanguageOnly

法语资源(法国)

dimensions.lang-fr-CA

LanguageOnly

法语资源(加拿大)

dimensions.lang-zh-CN

LanguageOnly

简体中文资源(中国)

本示例以“英语资源(英国)”的形式表示字符串资源的值,方便读者可以直观的看到在应用程序中资源候选项的匹配情况。

双击打开MainPage.xaml文件,在Grid元素中添加一个ComboBox控件、一个Button按钮和两个TextBlock文本块。在ComboBox控件中添加五个ComboBoxItem列表项,分别用来显示英语(英国)、英语(美国)、法语(法国)、法语(加拿大)和简体中文(中国)五种语言选项,并分别设置这五个列表项的Tag属性值为五种语言对应的标识符。然后设置ComboBox控件的SelectedValuePath属性的值为Tag,表示在后台代码中使用SelectedValue属性将获取到Tag属性的值。接下来设置Button按钮的Content属性值为“显示候选资源信息”,此按钮用于获取候选资源匹配列表并将其显示在一个TextBlock文本块中,另一个文本块则用来显示“选择应用语言”提示信息,代码如下所示:

<ComboBox SelectedValuePath="Tag" SelectedIndex="0" Name="LanguageComboBox" Margin="360,122,787,599">

    <ComboBoxItem Tag="en-GB">英语(英国)</ComboBoxItem>

    <ComboBoxItem Tag="en-US">英语(美国)</ComboBoxItem>

    <ComboBoxItem Tag="fr-FR">法语(法国)</ComboBoxItem>

    <ComboBoxItem Tag="fr-CA">法语(加拿大)</ComboBoxItem>

    <ComboBoxItem Tag="zh-CN">简体中文(中国)</ComboBoxItem>

</ComboBox>

<Button Name="ShowCandidateResources"  Content="显示候选资源信息" FontSize="20" Click="ShowCandidateResources_Click" Margin="612,118,0,594" Width="223" Height="56" />

<TextBlock Margin="360,225,0,0" HorizontalAlignment="Left" Name="CandidateResources" FontSize="20" Height="412" TextWrapping="Wrap"  VerticalAlignment="Top" Width="648"/>

<TextBlock HorizontalAlignment="Left" Margin="514,63,0,0" TextWrapping="Wrap" Text="选择应用语言" FontSize="25" VerticalAlignment="Top" Height="34" Width="157"/>

这时运行此页面,单击ComboBox控件的文本框,可展开下拉列表查看5种语言选项,如图18-31所示。在后台添加代码以后,可以选择列表中的一种语言作为应用的首选语言,然后单击“显示候选资源信息”按钮查看资源候选项匹配列表信息。

图18-31 选择应用语言界面

下面在MainPage.xaml.cs文件中添加单击“显示候选资源信息”按钮后的事件处理方法ShowCandidateResources_Click,此方法用于显示资源候选项匹配列表信息,代码如下所示:

using Windows.ApplicationModel.Resources.Core;

 

private void ShowCandidateResources_Click(object sender, RoutedEventArgs e)

{

    //新建一个ResourceContext类的对象context,用于存储应用的上下文环境

    var context = new ResourceContext();

    //定义selectedLanguage变量存储选择语言所对应的Tag属性值

    var selectedLanguage = LanguageComboBox.SelectedValue;

context.QualifierValues["Language"] = selectedLanguage.ToString();

//调用SearchResource方法用于在项目中查找资源

    SearchResource(context, "LanguageOnly");

}

上面的代码首先新建了一个ResourceContext类的对象context,用于存储应用的上下文环境。然后定义一个selectedLanguage变量用于存储在ComboBox下拉列表中选择项的语言标记信息。接着调用ToString方法把selectedLanguage变量转化为字符串,将其以键值对形式保存在context对象的QualifierValues属性的"Language"键中。最后以context对象和资源名称"LanguageOnly"作为参数调用SearchResource方法,用于在项目中查找资源候选项。下面来看一下SearchResource方法的实现代码。

在SearchResource方法中添加了查找资源的过程,代码如下所示:

void SearchResource(ResourceContext context, string resourceId)

{

    //定义一个dimensionMap对象用于访问资源文件

ResourceMap dimensionMap = ResourceManager.Current.MainResourceMap.GetSubtree("dimensions");

//声明一个NamedResource类的对象namedResource

    NamedResource namedResource;

    if (dimensionMap.TryGetValue(resourceId, out namedResource))

    {

        var resourceCandidates = namedResource.ResolveAll(context);

        //调用ShowCandidates方法显示候选资源

        ShowCandidates(resourceId, resourceCandidates);

    }

}

上面的代码新建了一个ResourceMap类的对象dimensonMap,以项目中资源文件名的前半部分“dimensions”作为参数调用ResourceManager类的Current成员中的MainResourcesMap成员所提供的GetSubtree方法,将返回结果赋给resourceStringMap对象。这样resourceStringMap对象便可以访问文件名前半部分为“dimensions”的资源文件。

声明一个NamedResource类的对象namedResource用于获取字符串资源的值。然后使用SearchResource方法的参数resourceId作为调用dimensionMap对象的TryGetValue方法的第一个参数,第二个为引用参数,用于将获取的资源值赋给namedResource。TryGetValue方法返回一个bool类型的值,当nameResource对象不为空时返回值True,则以context对象作为参数调用namedResource对象的ResolveAll方法,将所有候选资源项按优先顺序存储在resourceCandidates对象中,然后以SearchResource方法的参数resourceId和resourceCandidates对象作为参数调用ShowCandidates方法来显示候选资源的相关信息。下面再来看一下ShowCandidates方法的实现代码。

在ShowCandidates方法很简单,只是通过遍历的方法将各个候选资源名称、语言代码和是否匹配应用等信息显示在界面上,代码如下所示:

void ShowCandidates(string resourceId, IReadOnlyList<ResourceCandidate> resourceCandidates)

{

    string outText = "资源名称: " + resourceId + "\r\n";

    int number = 1;

    //遍历resourceCandidates对象中的候选资源

    foreach (var candidate in resourceCandidates)

    {

        var value = candidate.ValueAsString;

        outText += "    候选资源 " + number.ToString() + ":" + value + "\r\n";

        foreach (var qualifier in candidate.Qualifiers)

        {

            //将语言的标识符、是否匹配应用等信息显示出来

            var qualifierValue = qualifier.QualifierValue;

            outText += "        语言标识符: " + qualifierValue + "\r\n";

            outText += "        是否匹配应用: 匹配 (" + qualifier.IsMatch.ToString() + ")  " + "默认语言 (" + qualifier.IsDefault.ToString() + ")" + "\r\n";

        }

        number++;

    }

    CandidateResources.Text += outText + "\r\n";

}

运行程序,在应用界面中选择英语(英国)作为应用的首选语言,单击“显示候选资源信息”按钮,会看到资源候选项对应语言的匹配顺序为“英语(英国)”、“英语(美国)”、“简体中文(中国)”、“法语(法国)”和“法语(加拿大)”,效果如图18-32所示。

图18-32 选取匹配语言

从图18-32可以看到,应用对这些资源候选项的匹配顺序就是本小节开始讲述的规则,候选资源1:英语资源(英国)为应用的首选资源项。以上就是资源匹配的相关知识点。为了巩固本章所学知识,下节为读者总结一个全球化示例。

Windows Store App 全球化 资源匹配规则的更多相关文章

  1. Windows Store App 全球化 设置指定页面的语言

    上一小节介绍了通过在应用程序中添加语言设置选项来改变整个应用显示信息的语言,而有时用户只想对应用中某一页面信息的语言进行调整,这时就不能使用上一小节所讲述的知识来对应用进行设置.下面将通过一个示例介绍 ...

  2. Windows Store App 全球化:引用类库资源

    前面几个小节介绍了如何引用自身项目的资源,而有时在应用程序开发过程中可能需要访问其他项目中的资源.例如,当几个人或十几个人一起设计一个解决方案时,每个人的工作都是不同的,编写的项目也是不同的,但是每个 ...

  3. Windows Store App 全球化:引用分离资源文件中的资源

    大部分应用程序仅需要单个默认资源文件,例如Strings/zh-CN/Resources.resw,但是在某些应用程序中,最好将资源分离到多个资源文件中,以便更好地组织资源内容,这样就需要考虑如何引用 ...

  4. Windows Store App 全球化:在XAML元素中引用文件资源

    上一小节讲解了如何在XAML元素中使用x:Uid属性引用资源文件中的字符串资源,通过改变语言首选项显示不同的运行结果.如果把字符串资源变成文件资源,就不能使用x:Uid属性来引用这些文件资源.本小节将 ...

  5. Windows Store App 全球化:应用中设置语言选项

    当开发者将开发的应用上传到Windows应用商店以后,使用Windows 8系统的用户可能会看到并下载这些应用,而这些用户所在的区域或者所使用的语言可能都不相同,如果他们在使用应用程序时希望改变应用显 ...

  6. Windows Store App 全球化:运行时响应语言变更

    在应用程序运行过程中,系统的语言.像素.对比度等系统设置可能会发生改变,应用程序应根据系统环境的改变及时做出适当的响应.为了解决这样的问题,可以在应用程序中为系统状态更改事件注册事件处理方法,当语言. ...

  7. Windows Store App 全球化:在后台代码中引用字符串资源

    上文提到了引用字符串资源具有两种方式,分别是在XAML元素中和在后台代码中引用资源文件中的字符串资源.在第一小节已经介绍了如何在XAML元素中引用字符串资源,本小节将讲解在后台代码中引用字符串资源的相 ...

  8. Windows Store App 全球化:在XAML元素中引用字符串资源

    在应用程序中可以通过XAML元素和后台代码两种方式引用资源文件中的字符串资源.本小节先讲述如何在XAML元素中引用字符串资源的相关知识点. 在XAML元素中可以通过使用x:Uid属性来引用资源文件中的 ...

  9. 在桌面程序上和Metro/Modern/Windows store app的交互(相互打开,配置读取)

    这个标题真是取得我都觉得蛋疼..微软改名狂魔搞得我都不知道要叫哪个好.. 这边记录一下自己的桌面程序跟windows store app交互的过程. 由于某些原因,微软的商店应用的安全沙箱导致很多事情 ...

随机推荐

  1. js函数的传参是按值传对递

    根据js高级程序设计第三版编写,对于函数的参数只能按值传递是这样解释的: ECMAScript 中所有函数的参数都是按值传递的.也就是说,把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另 ...

  2. CSU 1660 K-Cycle(dfs判断无向图中是否存在长度为K的环)

    题意:给你一个无向图,判断是否存在长度为K的环. 思路:dfs遍历以每一个点为起点是否存在长度为k的环.dfs(now,last,step)中的now表示当前点,last表示上一个访问的 点,step ...

  3. [TCPIP] 分层 Note

    TCP/IP  分层 TCP/IP是一组不同层次上的多个协议的组合. 通常被分为:链路层.网络层.运输层.应用层 1. 链路层(数据链路层 或 网络接口层) 通常包括操作系统中的设备驱动程序和计算机中 ...

  4. angular的ng-repeat使用

    ng-repeat是angular的一个指令,用来循环生成某些东西.常用的是拿到数据循环生成样式展示在视图中. <!--orderStatuses表示$scope传递的数据$scope.orde ...

  5. centos6.6_64位操作系统安装时候出现kernel panic - not syncing: Attempted to kill init 解决办法

    最近在VM上安装centos时候经常被这个问题虐,后来进入单用户模式在   kernel /vmlinuz-XXXXro root=/dev/vogroup00/logvol00 rhgb quie  ...

  6. linux驱动中printk的使用注意事项

    今天在按键驱动中增加printk(KERN_INFO "gpio_keys_gpio_isr()\n");在驱动加载阶段可以输出调试信息,但驱动加载起来后的信息,在串口端看不到输出 ...

  7. 今天学的是 HTML基本元素、基本语法元素特点等,就发图片吧。

    现在我们新手用的软件是:Adobe Dreamweaver CS6 按照下面格式来改,以后点HTML5直接就改过来了. 可以敲敲这些代码,大家一起学习. <!doctype html>&l ...

  8. 【转】}目前比较全的CSS重设(reset)方法总结

    在当今网页设计/开发实践中,使用CSS来为语义化的(X)HTML标记添加样式风格是重要的关键.在设计师们的梦想中都存在着这样的一个完美世界:所有的浏览器都能够理解和适用多有CSS规则,并且呈现相同的视 ...

  9. jquery总结06-动画事件01-基础显示和隐藏

    动画事件 .hide(option) 动画隐藏  会保存元素的原始属性值 $("#a2").hide({ duration: 3000, complete: function() ...

  10. /etc/xinetd.conf 和 /etc/xinetd.d/*【新网络服务配置】

    http://blog.csdn.net/kelven2004/article/details/1701930 xinetd 是 inetd 的安全加强版,它内置了自己的 TCP wrapper, 可 ...