让程序支持多语言,一般把需要显示的字符串保存在一个资源类的static属性中。

<!--[if !supportLists]--> <!--[endif]-->

微软的WPF程序多语言支持官方解决方案:使用Resource,并把Resource按语言编译成独立DLL,程序会根据系统当前语言设置,自动加载最合适的资源。(这种方法灵活性较差,而且不能满足多样的需求,于是网上各种多语言方案纷至沓来。)这里有一篇对官方方案的进一步解释。

使用XML保存语言文件:放进来只是因为网上的确有这么个解释方案,虽然没有什么实用价值……,Resource本来就是XML,还用自己定义一个XML,还XMLDataProvider,还XML-based Data Binding,看着都累…… 
使用Project Resource的:和上面的类似,不过把字符串全放在Project Resource里,然后用ObjectDataProvider,然后也是使用Data Binding。

Assembly自带语言:每个Assembly里放上支持的所有语言,使用配置文件设置软件语言,比微软的方案更进一步,但是WPF程序多语言支持问题也还是存在的。

<!--[if !supportLists]--><!--[endif]--><!--[if !supportLists]--><!--[endif]--><!--[if !supportLists]--><!--[endif]-->

上面所有的方案都没有同时解决下面这两个问题:

<!--[if !supportLists]--> <!--[endif]-->

运行时切换语言。

加入新语言,而不需要重新编译软件。

<!--[if !supportLists]--><!--[endif]--> 
下面,就来介绍一种更灵活的,解决了上面两个问题的WPF程序多语言支持方案。

基本方式还是使用Resource,只不过Resource是运行时才加载进来的。解决方案的结构如下图所示。

其中各个语言文件的资源文件放在Resources/Langs文件夹中,这些资源文件不会被编译到Assembly中,编译之后的文件结构如下图所示,语言文件被原样复制到Output文件夹中。

先来看看程序的运行效果,再来看代码会比较直观一些。

下面就是这个界面的代码。

  1. MainWindow
  2. <Window x:Class="Localization.DemoWindow"
  3. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  4. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  5. xmlns:c="clr-namespace:Localization.Backend.Commands"
  6. Title="{DynamicResource MainWindowTitle}"
  7. Width="230" Height="150">
  8. <DockPanel LastChildFill="False">
  9. <Menu DockPanel.Dock="Top">
  10. <Menu.CommandBindings>
  11. <x:Static Member="c:LanguageCommands.OpenLanguageBinding"/>
  12. </< SPAN>Menu.CommandBindings>
  13. <MenuItem Header="{DynamicResource LanguageMenuHeader}">
  14. <MenuItem Header="{DynamicResource EnglishMenuHeader}"
  15. Click="OnLoadEnglishClick"/>
  16. <MenuItem Header="{DynamicResource ChineseMenuHeader}"
  17. Click="OnLoadChineseClick" />
  18. <Separator/>
  19. <MenuItem Command="c:LanguageCommands.OpenLanguage"
  20. Header="{DynamicResource OpenLanguageFileMenuHeader}"/>
  21. </< SPAN>MenuItem>
  22. </< SPAN>Menu>
  23. </< SPAN>DockPanel>
  24. </< SPAN>Window>

所有的界面上的文字,都使用DynamicResource引用资源文件中的字符串。资源文件的格式如下(英文资源文件示例):

  1. <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  2. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  3. xmlns:s="clr-namespace:System;assembly=mscorlib">
  4. <s:String x:Key="MainWindowTitle">Localization Demo</< SPAN>s:String>
  5. <s:String x:Key="LanguageMenuHeader">_Language</< SPAN>s:String>
  6. <s:String x:Key="EnglishMenuHeader">_English</< SPAN>s:String>
  7. <s:String x:Key="ChineseMenuHeader">汉语(_C)</< SPAN>s:String>
  8. <s:String x:Key="OpenLanguageFileMenuHeader">_Open Language File</< SPAN>s:String>
  9. </< SPAN>ResourceDictionary>

语言文件没有编译到Assembly中,使用起来就有些不太一样。下面是App.xaml文件中设置Application的默认加载语言的方式。

  1. <Application x:Class="Localization.App"
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4. StartupUri="UI\DemoWindow.xaml">
  5. <Application.Resources>
  6. <ResourceDictionary>
  7. <ResourceDictionary.MergedDictionaries>
  8. <ResourceDictionary Source="pack://siteOfOrigin:,,,/Resources/Langs/en-US.xaml"/>
  9. </< SPAN>ResourceDictionary.MergedDictionaries>
  10. </< SPAN>ResourceDictionary>
  11. </< SPAN>Application.Resources>
  12. </< SPAN>Application>

前面的内容基本上没有什么和别的方案不一样的地方,下面才是最重要的一点,就是如何运行时切换语言的呢?答案就是,只要把上面代码里的ResourceDictionary替换掉就OK了,界面会自动刷新。下面就是实现替换功能的代码。

  1. public class LanguageHelper
  2. {
  3. /// <summary>
  4. ///
  5. /// </< SPAN>summary>
  6. /// <param name="languagefileName"></< SPAN>param>
  7. public static void LoadLanguageFile(string languagefileName)
  8. {
  9. Application.Current.Resources.MergedDictionaries[0] = new ResourceDictionary()
  10. {
  11. Source = new Uri(languagefileName, UriKind.RelativeOrAbsolute)
  12. };
  13. }
  14. }

参数languagefileName可以是文件的绝对路径,如:C:\en-US.xaml或是和App.xaml里一样的相对路径。顺便解释一下,那个“pack://siteOfOrigin:,,,”无非就是当前执行程序的所在目录。

以目前的测试结果来看,即使界面上有大量的细粒度文字。切换语言的速度也是一瞬间的事儿,如果慢,也是因为xaml文件过大,读文件用了不少时间。

WPF程序多语言支持缺陷

其实这才是最重要的,很多文章介绍一项技术的时候都会把这个技术夸得天花乱坠,却对潜在的缺陷或问题避而不谈。

缺陷就在于,不是所有的东西都是可以运行是更新的。比如最后一个菜单项是用Command实现的,如下代码所示:

  1. <MenuItem Command="c:LanguageCommands.OpenLanguage"
  2. Header="{DynamicResource OpenLanguageFileMenuHeader}"/>

RoutedUICommand本身就已经定义了Text属性用来显示在界面上,完全没有必要为使用了这个Command的MenuItem设置Header属性。但是这里为什么还是设置了呢?因为目前还没有找到简单的方案改变Command的Text后能自动地更新界面。因为Command的Text属性不是一个Dependency Property。为了自动更新界面,不得不为MenuItem设置Header属性。

WPF使用X:Static做多语言支持的更多相关文章

  1. 分享两种实现Winform程序的多语言支持的解决方案

    因公司业务需要,需要将原有的ERP系统加上支持繁体语言,但不能改变原有的编码方式,即:普通程序员感受不到编码有什么不同.经过我与几个同事的多番沟通,确定了以下两种方案: 方案一:在窗体基类中每次加载并 ...

  2. EnumHelper.cs枚举助手(枚举描述信息多语言支持)C#

    C#里面经常会用到枚举类型,枚举是值类型对象,如果你想用枚举类型的多属性特性,或者你想在MVC页面上通过简单的值类型转换,将某字段值所代表的含义转换为文字显示,这时候必须要将枚举扩展,是它支持文本描述 ...

  3. 【转】解析JDK 7的动态类型语言支持

    http://www.infoq.com/cn/articles/jdk-dynamically-typed-language Java虚拟机的字节码指令集的数量自从Sun公司的第一款Java虚拟机问 ...

  4. Windows 8本地化多语言支持

    原文:Windows 8本地化多语言支持 在Win8平台处理本地化多语言的支持相对比较容易的,但比WP8稍微复杂一点,并不像WP8平台那样大部分工作都有VS IDE处理,Win8平台的操作基本需要开发 ...

  5. Java学习笔记--脚本语言支持API

    Java语言的动态性之脚本语言支持API 随着Java平台的流行,很多的脚本语言(scripting language)都可以运行在Java虚拟机啊上,其中比较流行的有JavaScript.JRuby ...

  6. .NET Core中多语言支持

    在.NET Core项目中也是可以使用.resx资源文件,来为程序提供多语言支持.以下我们就以一个.NET Core控制台项目为例,来讲解资源文件的使用. 新建一个.NET Core控制台项目,然后我 ...

  7. Java语言支持的变量类型有哪几种

    Java语言支持的变量类型有: 类变量:独立于方法之外的变量,用 static 修饰. 实例变量:独立于方法之外的变量,不过没有 static 修饰. 局部变量:类的方法中的变量. 实例: publi ...

  8. Java语言支持的变量类型有

    Java语言支持的变量类型有: 类变量:独立于方法之外的变量,用 static 修饰. 实例变量:独立于方法之外的变量,不过没有 static 修饰. 局部变量:类的方法中的变量.

  9. JVM中的动态语言支持简介

    抽丝剥茧 细说架构那些事——[优锐课] 从版本6开始,JVM已扩展为支持现代动态语言(也称为脚本语言).Java8的发行为这一领域提供了更多动力.感到这种支持的必要性是因为Java作为一种语言固有地是 ...

随机推荐

  1. MySQL性能指标及计算方法 等待show processlist

    http://www.cnblogs.com/cyt1153/p/6697847.html http://www.cnblogs.com/cyt1153/tag/mysql/

  2. tiny4412 串口驱动分析五 --- LDD3上TTY驱动程序源码

    关于tty这部分请参考: <Linux设备驱动开发详解 第二版>第14章 Linux终端设备驱动 <精通Linux设备驱动程序开发>第6章 串行设备驱动程序 <Linux ...

  3. DELPHI的一些开源项目GIT地址

    DELPHI的一些开源项目GIT地址 Delphi-Cross-Sockethttps://github.com/winddriver/Delphi-Cross-Socket 跨平台的SOCKET库 ...

  4. IntelliJ IDEA 配合 Maven 的一些技巧:Profiles

    环境 IntelliJ IDEA 2017.1 Maven 3.3.9 Nexus 3.2.1 学习前提 了解 Maven 配置的基本用法 了解私有仓库,比如 nexus 的一些概念 强烈建议把 Ma ...

  5. 用nodejs和js写增删查模块

    文件目录如下:public是静态资源文件,index.html入门页面,server.js就是用nodejs创建的服务端代码,users.json就类似是数据库. 目录 显示界面 listUsers ...

  6. Nginx为什么比Apache Httpd高效

    转载于:http://www.toxingwang.com/linux-unix/linux-basic/1712.html 一.进程.线程? 在回答nginx 为什么比apache更高效之前,必须要 ...

  7. oc 之中的 汉字字符串转化成为拼音 汉字字符串的排序

    在oc 之中的字符串为汉字的时候,我们经常要进行字符串比較,可是汉字不能比較,所以就要将汉字转化成为拼音,详细步骤例如以下: //可变字符串 必须是可变字符串.     NSMutableString ...

  8. Android Tabhost置于底部

    方法一: <TabHost xmlns:android="http://schemas.android.com/apk/res/android" android:id=&qu ...

  9. Android学习(七) Android实现计算器

    前台页面代码,通过线性布局方式实现计算器页面:如图所示 color.xml,自定义颜色values: <?xml version="1.0" encoding="u ...

  10. Laravel之目录结构

    一.根目录 新安装的 Laravel 应用包含许多文件夹:• app 目录包含了应用的核心代码:• bootstrap 目录包含了少许文件用于框架的启动和自动载入配置,还有一个cache 文件夹用于包 ...