注意到语言名称并没有出现在上面的XML文件中。这是因为本地化语言名称放在一个单独的XML文件中定义,LanguageNames.xml: 02 | <Language code= "en" >English</Language> |
03 | <Language code= "ar" >العربية</Language> |
04 | <Language code= "de" >Deutsch</Language> |
05 | <Language code= "el" >Ελληνικά</Language> |
06 | <Language code= "es" >Español</Language> |
07 | <Language code= "fr" >Franç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> |
每种语言定义文件的命名遵循这样一个惯例, 'LangXX.xml'.其中,XX 与两个字母的 ISO语言代码相对应,LanguageNames.xml中的每个Language元素也该代码对应。当然,这一惯例可以拓展或修改为易于处理本地化(如 en-NZ, en-US),甚至改成三字母的ISO语言代码。 UILanguageDefn类在语言定义文件中的当前界面语言数据被加载进一个内部类(UILanguageDefn)中是为了被剩下的应用消耗掉。主要的组件是一个<string, string>类型的字典。这个字典包含了从文本键到局部的文本值的映射。其它的属性显示:IsRtl(是否右对齐),MinFontSize(最小字体大小)和HeadingFontSize的值。 当你使用这个类的时候,局部语言文本会通过调用下面的方法重新取回: 02 | /// Gets the localised text value for the given key. |
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 > |
06 | public string GetTextValue(string key) |
08 | if (_uiText.ContainsKey(key)) |
除此之外,UILanguageDefn类有一个静态的从语言编码到局部的语言名称的映射(这个映射是从LanguageNames.xml中加载进来的),例如,“en”和“English”、“sv”和“Svenska”。这被用来填充到'Language'标签的可用语言列表中,而且被应用所支持的权威的语言列表过滤。因此,任何不再这个列表的语言不会被界面所显示。即使有一个语言定义文件或在LanguageNames.xml中有所对应的实体,也不会显示这个语言。这会在下面的章节中进一步介绍。 加载数据类`UILanguageDefn`形成模型的一部分。模型里面的第二个主要的实体就是应用全状态,`MainWindowModel`。它包含了被整个应用程序使用的`UILanguageDefn`的授权的实例。这是在全部界面中获取文本元素的边界的实例。(通过ViewModel)。 当`MainWindowModel`被构造时,在加载当前语言之前,首先会注册语言列表的授权和从名字为LanguageNames.xml的资源文件中加载本地化语言。下面通过例子让我们看看它是如何工作的: 01 | public class MainWindowModel |
03 | private UILanguageDefn _languageMapping; |
05 | public MainWindowModel( int maxWidth, int maxHeight) |
15 | public string CurrentLanguageCode |
25 | /// Registers the languages by their corresponding ISO code. |
27 | private void RegisterLanguages() |
30 | string [] supportedLanguageCodes = |
32 | "en" , "ar" , "de" , "el" , |
33 | "es" , "fr" , "ko" , "hi" , |
34 | "it" , "he" , "jp" , "ru" , "sv" |
37 | foreach ( string languageCode in supportedLanguageCodes) |
38 | UILanguageDefn.RegisterSupportedLanguage(languageCode); |
42 | /// Loads the list of available languages from the embedded XML resource. |
44 | private void LoadLanguageList() |
47 | string resourcePath = "RePaverModel.LanguageData.LanguageNames.xml" ; |
49 | System.IO.Stream file = |
50 | Assembly.GetExecutingAssembly().GetManifestResourceStream(resourcePath); |
52 | XmlDocument languageNames = new XmlDocument(); |
53 | languageNames.Load(file); |
55 | UILanguageDefn.LoadLanguageNames(languageNames.DocumentElement); |
59 | /// Updates the UI language data from that |
60 | /// defined in the corresponding language file. |
63 | public bool UpdateLanguageData() |
65 | string languageCode = CurrentLanguageCode; |
66 | if (String.IsNullOrEmpty(languageCode)) return false ; |
72 | String.Format(Constants.LanguageDefnPathTemplate, languageCode.ToUpper()); |
73 | System.IO.Stream file = |
74 | Assembly.GetExecutingAssembly().GetManifestResourceStream(resourcePath); |
76 | XmlDocument languageData = new XmlDocument(); |
77 | languageData.Load(file); |
79 | _languageMapping = new UILanguageDefn(); |
80 | _languageMapping.LoadLanguageData(languageData.DocumentElement); |
你可能注意到上面的代码提到了第三个主体 - 设置状态。在众多可在运行时调整的设置中,正是这个状态存储了当前正被使用的接口语言。大多数的设置项都在应用程序关闭后保存在磁盘中,当程序再次打开时就重新加载出来。 然而,如果应用程序是第一次打开(没有设置文件存在),那么这些设置就会被设定为默认状态。对于语言来说,英语是默认的,但这并不是用户友好(user-friendly)的。所以呢,我们就这样检索当前系统语言: 1 | CultureInfo.CurrentCulture.TwoLetterISOLanguageName; |
找到相应的语言后,如果应用程序不支持该语言,就让英语作为默认语言。这样,只要你的本地语言受支持,UI就会在你程序第一次运行时显示该语言。在Setting model hierarchy中,有如下代码 01 | public LanguageSettings() |
06 | _uiLanguageCode = Constants.DefaultLanguageCode; |
08 | string languageCode = CultureInfo.CurrentCulture.TwoLetterISOLanguageName; |
13 | if (UILanguageDefn.AllSupportedLanguageCodes.Contains(languageCode)) |
14 | _uiLanguageCode = languageCode; |
这个类中的另一种方法,姑且叫做后者吧 (有用户设置文件存在的时候使用),它会提取保存在文件中的设置项的值,并把它复写到_uiLanguageCode.
|