设为首页收藏本站

LUPA开源社区

 找回密码
 注册
文章 帖子 博客
LUPA开源社区 首页 业界资讯 技术文摘 查看内容

构建多语言的WPF应用

2014-7-9 10:25| 发布者: joejoe0332| 查看: 6033| 评论: 0|原作者: 徐继开, TimBao, chasehong, 无若, 0x0bject, 请叫我益达张, 卖茄子, 地狱星星|来自: oschina

摘要: 在WPF应用程序中搭建多语言支持(Multilingual Support)是我最近在做的一件事,对于不使用英语的人士而言,此举提高了程序的可用性。实现起来要完成以下目标:…… ...


注意到语言名称并没有出现在上面的XML文件中。这是因为本地化语言名称放在一个单独的XML文件中定义,LanguageNames.xml:

01<LangNames>
02    <Language code="en">English</Language>
03    <Language code="ar">العربية</Language>
04    <Language code="de">Deutsch</Language>
05    <Language code="el">&Epsilon;&lambda;&lambda;&eta;&nu;&iota;&kappa;ά</Language>
06    <Language code="es">Espa&ntilde;ol</Language>
07    <Language code="fr">Fran&ccedil;ais</Language>
08    <Language code="he">עברית</Language>
09    <Language code="hi">हिन्दी</Language>
10    <Language code="it">Italiano</Language>
11    <Language code="jp">日本語</Language>
12    <Language code="ko">한국어</Language>
13    <Language code="ru">Русский</Language>
14    <Language code="sv">Svenska</Language>
15</LangNames>

每种语言定义文件的命名遵循这样一个惯例, 'LangXX.xml'.其中,XX 与两个字母的 ISO语言代码相对应,LanguageNames.xml中的每个Language元素也该代码对应。当然,这一惯例可以拓展或修改为易于处理本地化(如 en-NZ, en-US),甚至改成三字母的ISO语言代码。

UILanguageDefn类

在语言定义文件中的当前界面语言数据被加载进一个内部类(UILanguageDefn)中是为了被剩下的应用消耗掉。主要的组件是一个<string, string>类型的字典。这个字典包含了从文本键到局部的文本值的映射。其它的属性显示:IsRtl(是否右对齐),MinFontSize(最小字体大小)和HeadingFontSize的值。

当你使用这个类的时候,局部语言文本会通过调用下面的方法重新取回:

01/// <summary>
02/// Gets the localised text value for the given key.
03/// </summary>
04/// <param name="key">The key of the localised text to retrieve.</param>
05/// <returns>The localised text if found, otherwise an empty string.</returns>
06public string GetTextValue(string key)
07{
08    if (_uiText.ContainsKey(key))
09        return _uiText[key];
10 
11    return "";
12}

除此之外,UILanguageDefn类有一个静态的从语言编码到局部的语言名称的映射(这个映射是从LanguageNames.xml中加载进来的),例如,“en”和“English”、“sv”和“Svenska”。这被用来填充到'Language'标签的可用语言列表中,而且被应用所支持的权威的语言列表过滤。因此,任何不再这个列表的语言不会被界面所显示。即使有一个语言定义文件或在LanguageNames.xml中有所对应的实体,也不会显示这个语言。这会在下面的章节中进一步介绍。

加载数据

类`UILanguageDefn`形成模型的一部分。模型里面的第二个主要的实体就是应用全状态,`MainWindowModel`。它包含了被整个应用程序使用的`UILanguageDefn`的授权的实例。这是在全部界面中获取文本元素的边界的实例。(通过ViewModel)。

当`MainWindowModel`被构造时,在加载当前语言之前,首先会注册语言列表的授权和从名字为LanguageNames.xml的资源文件中加载本地化语言。下面通过例子让我们看看它是如何工作的:

01public class MainWindowModel
02{
03    private UILanguageDefn _languageMapping;
04 
05    public MainWindowModel(int maxWidth, int maxHeight)
06    {
07        RegisterLanguages();
08        LoadLanguageList();
09         
10        //Settings are loaded here, where CurrentLanguageCode is decided.
11 
12        UpdateLanguageData();
13    }
14     
15    public string CurrentLanguageCode
16    {
17        get 
18        {
19            // Retrieves the current language code from
20            // the Settings model (abstracted away)
21        }
22    }
23     
24    /// <summary>
25    /// Registers the languages by their corresponding ISO code.
26    /// </summary>
27    private void RegisterLanguages()
28    {
29        // Defined in Constants class
30        string[] supportedLanguageCodes =
31        {
32            "en""ar""de""el"
33            "es""fr""ko""hi"
34            "it""he""jp""ru""sv"  
35        };
36         
37        foreach(string languageCode in supportedLanguageCodes)
38            UILanguageDefn.RegisterSupportedLanguage(languageCode);
39    }
40 
41    /// <summary>
42    /// Loads the list of available languages from the embedded XML resource.
43    /// </summary>
44    private void LoadLanguageList()
45    {
46        // Defined in Constants class
47        string resourcePath = "RePaverModel.LanguageData.LanguageNames.xml";
48         
49        System.IO.Stream file =
50                Assembly.GetExecutingAssembly().GetManifestResourceStream(resourcePath);
51 
52        XmlDocument languageNames = new XmlDocument();
53        languageNames.Load(file);
54 
55        UILanguageDefn.LoadLanguageNames(languageNames.DocumentElement);
56    }
57 
58    /// <summary>
59    /// Updates the UI language data from that
60    /// defined in the corresponding language file.
61    /// </summary>
62    /// <returns>
63    public bool UpdateLanguageData()
64    {
65        string languageCode = CurrentLanguageCode;
66        if (String.IsNullOrEmpty(languageCode)) return false;
67 
68        //This follows a convention for language definition files
69        //to be named &apos;LangXX.xml&apos; (or &apos;LangXX-XX.xml&apos;)
70        //where XX is the ISO language code.
71        string resourcePath = 
72          String.Format(Constants.LanguageDefnPathTemplate, languageCode.ToUpper());
73        System.IO.Stream file =
74            Assembly.GetExecutingAssembly().GetManifestResourceStream(resourcePath);
75 
76        XmlDocument languageData = new XmlDocument();
77        languageData.Load(file);
78 
79        _languageMapping = new UILanguageDefn();
80        _languageMapping.LoadLanguageData(languageData.DocumentElement);
81 
82        return true;
83    }
84}

你可能注意到上面的代码提到了第三个主体 - 设置状态。在众多可在运行时调整的设置中,正是这个状态存储了当前正被使用的接口语言。大多数的设置项都在应用程序关闭后保存在磁盘中,当程序再次打开时就重新加载出来。

然而,如果应用程序是第一次打开(没有设置文件存在),那么这些设置就会被设定为默认状态。对于语言来说,英语是默认的,但这并不是用户友好(user-friendly)的。所以呢,我们就这样检索当前系统语言:

1CultureInfo.CurrentCulture.TwoLetterISOLanguageName;

找到相应的语言后,如果应用程序不支持该语言,就让英语作为默认语言。这样,只要你的本地语言受支持,UI就会在你程序第一次运行时显示该语言。在Setting model hierarchy中,有如下代码

01public LanguageSettings()
02{
03    // Initialise the default language code.
04    // In most cases this will be overwritten by the
05    // restored value from the saved settings, or that of the current culture.
06    _uiLanguageCode = Constants.DefaultLanguageCode;     //"en"
07 
08    string languageCode = CultureInfo.CurrentCulture.TwoLetterISOLanguageName;
09 
10    // If the system language is supported, this will
11    // ensure that the application first loads
12    // with the UI displayed in that language.
13    if (UILanguageDefn.AllSupportedLanguageCodes.Contains(languageCode))
14        _uiLanguageCode = languageCode;
15}

这个类中的另一种方法,姑且叫做后者吧 (有用户设置文件存在的时候使用),它会提取保存在文件中的设置项的值,并把它复写到_uiLanguageCode.



酷毙

雷人

鲜花

鸡蛋

漂亮
  • 快毕业了,没工作经验,
    找份工作好难啊?
    赶紧去人才芯片公司磨练吧!!

最新评论

关于LUPA|人才芯片工程|人才招聘|LUPA认证|LUPA教育|LUPA开源社区 ( 浙B2-20090187 浙公网安备 33010602006705号   

返回顶部