WPF使用X:Static做多语言支持

简介: 原文:WPF使用X:Static做多语言支持让程序支持多语言,一般把需要显示的字符串保存在一个资源类的static属性中。   微软的WPF程序多语言支持官方解决方案:使用Resource,并把Resource按语言编译成独立DLL,程序会根据系统当前语言设置,自动加载最合适的资源。
原文: WPF使用X:Static做多语言支持

让程序支持多语言,一般把需要显示的字符串保存在一个资源类的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属性。

目录
相关文章
|
C#
WPF 界面实现多语言支持 中英文切换 动态加载资源字典
原文:WPF 界面实现多语言支持 中英文切换 动态加载资源字典 1、使用资源字典,首先新建两个字典文件en-us.xaml、zh-cn.xaml。定义中英文的字符串在这里面【注意:添加xmlns:s="clr-namespace:System;assembly=mscorlib】 zh-cn.
2894 0
|
自然语言处理 C# C++
WPF 多语言解决方案 - Multilingual App Toolkit
原文:WPF 多语言解决方案 - Multilingual App Toolkit 1、首先安装Multilingual App Toolkit   2、新建项目,在VS中点击"工具" -> "Multilingual App Toolkit" -> "启用选定内容"     如果出现上述Issue, 打开项目AssemblyInfo.
2328 0
|
XML 自然语言处理 C#
WPF 多语言实现
原文:WPF 多语言实现 很多国际化的程序都提供了多语言的选项,这样方便不同国家的使用者更方便的使用软件。这篇博客中将介绍在WPF中实现多语言的方式。 方式一,使用WPF动态资源的方式实现。先简单介绍下StaticResource和DynamicResource,这两者的区别在于动态资源改变后会实时的体现出来,而静态资源只加载一次,后面对资源的任何改变都不会体现出来。
1507 0
|
15天前
|
C# 开发者 Windows
基于Material Design风格开源、易用、强大的WPF UI控件库
基于Material Design风格开源、易用、强大的WPF UI控件库
|
4月前
|
C#
浅谈WPF之装饰器实现控件锚点
使用过visio的都知道,在绘制流程图时,当选择或鼠标移动到控件时,都会在控件的四周出现锚点,以便于修改大小,移动位置,或连接线等,那此功能是如何实现的呢?在WPF开发中,想要在控件四周实现锚点,可以通过装饰器来实现,今天通过一个简单的小例子,简述如何在WPF开发中,应用装饰器,仅供学习分享使用,如有不足之处,还请指正。
65 1
|
8月前
|
C# Windows
WPF技术之图形系列Polygon控件
WPF Polygon是Windows Presentation Foundation (WPF)框架中的一个标记元素,用于绘制多边形形状。它可以通过设置多个点的坐标来定义多边形的形状,可以绘制任意复杂度的多边形。
456 0
|
8月前
|
C# Windows
WPF技术之RichTextBox控件
WPF RichTextBox是Windows Presentation Foundation (WPF)中提供的一个强大的文本编辑控件,它可以显示富文本格式的文本,支持多种文本处理操作。
346 0
|
4月前
|
前端开发 C# 容器
浅谈WPF之控件拖拽与拖动
使用过office的visio软件画图的小伙伴都知道,画图软件分为两部分,左侧图形库,存放各种图标,右侧是一个画布,将左侧图形库的图标控件拖拽到右侧画布,就会生成一个新的控件,并且可以自由拖动。那如何在WPF程序中,实现类似的功能呢?今天就以一个简单的小例子,简述如何在WPF中实现控件的拖拽和拖动,仅供学习分享使用,如有不足之处,还请指正。
108 2
|
8月前
|
数据挖掘 数据处理 C#
WPF技术之DataGrid控件
WPF DataGrid是一种可以显示和编辑数据的界面控件。它可以作为表格形式展示数据,支持添加、删除、修改、排序和分组操作。
180 0
|
16天前
|
C# 开发者 C++
一套开源、强大且美观的WPF UI控件库
一套开源、强大且美观的WPF UI控件库
129 0