WPF应用程序支持多国语言解决方案

简介: 原文:WPF应用程序支持多国语言解决方案 促使程序赢得更多客户的最好、最经济的方法是使之支持多国语言,而不是将潜在的客户群限制为全球近70亿人口中的一小部分。本文介绍四种实现WPF应用程序支持多国语言的解决方案。
原文: WPF应用程序支持多国语言解决方案

猛击这里下载源代码

促使程序赢得更多客户的最好、最经济的方法是使之支持多国语言,而不是将潜在的客户群限制为全球近70亿人口中的一小部分。本文介绍四种实现WPF应用程序支持多国语言的解决方案。

效果如下图:

Language - en-US (英文)

Language - zh-CN (中文)

阅读目录

一、使用LocBaml工具

二、使用资源字典文件

三、使用.resx资源文件

四、实现动态切换程序显示语言

附:实现MessageBox支持多语言

一、使用LocBaml工具

这是微软MSDN给出的一种解决方案,请参见如何:对应用程序进行本地化。这种方式操作相对繁琐,不能方便的实现在程序运行过程中动态切换语言,但是新增支持语言无需对项目重新编译,这是这种实现方式的一个亮点。

1. 设置默认语言环境

项目文件LocalizationDemo.csproj添加<UICulture>en-US</UICulture>,程序集文件AssemblyInfo.cs中把[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]注释去掉。

2. 在xaml文件中添加Uid

打开Visual Studio 命令提示(2010)如下图,进入项目文件.csproj所在目录,运行命令:msbuild /t:updateuid LocalizationDemo.csproj若要验证是否缺少或重复Uid,运行命令:msbuild /t:checkuid LocalizationDemo.csproj。

3. 通过Localization.Attributes,设置本地化的特性(属性)

如:<DataGridTextColumn x:Uid="DataGridTextColumn_1" Header="No." Width="auto" Binding="{Binding No}" Localization.Attributes="$Content(Ignore) Width(Ignore) Header(None Readable Modifiable)"/>,这里Width(Ignore)设置Width属性不实现本地化,Header(None Readable Modifiable)设置Header属性可读可写需要实现本地化,更多本地化特性细节请参见本地化特性和注释

4. 编译项目,生成语言资源文件

生成的LocalizationDemo.resources.dll会在\bin\Debug\en-US\目录下。

5. 将语言资源文件输出存储为 .csv 文件,以作进一步分析

将 LocBaml.exe(LocBaml 工具是一种尚未投产使用的应用程序。它显示为一种示例,该示例使用某些本地化 API 并演示如何编写本地化工具。点击下载LocBaml)复制到应用程序的 bin\debug 文件夹,即创建主应用程序集的位置。打开Visual Studio 命令提示(2010),进入bin\debug目录,运行命令:LocBaml.exe /parse en-US/LocalizationDemo.resources.dll /out:en-US.csv

6. 翻译可本地化内容

注意此步应当使用兼容unicode的文本编辑器进行编辑翻译。或者中文系统下将 .csv 文件在 Microsoft Excel 中进行查看,对最后一列(值)进行翻译更改,另存为zh-CN.csv。

此时会弹出如下消息提示框,选择"是(Y)",

然后用记事本打开zh-CN.csv文件,选择"另存为",如下图(初始编码为"ANSI")选择"UTF-8"保存。

7. 使用 LocBaml 生成新增语言的.resources.dll资源文件

运行下面命令根据翻译的zh-CN.csv生成中文资源文件LocalizationDemo.resources.dll,可以在E:\目录下找到,将生成的LocalizationDemo.resources.dll复制到项目\bin\Debug\zh-CN\目录下即可。

LocBaml.exe /generate en-US/LocalizationDemo.resources.dll /trans:zh-CN.csv /out:E:\ /cul:zh-CN

8. 测试新增语言资源文件

  • 更改操作系统的地区设置(“开始” | 控制面板 |“区域和语言选项”)。
  • 代码中控制
1       //中文为: "zh-CN"
2       CultureInfo ci = new CultureInfo("en-US");
3       Thread.CurrentThread.CurrentCulture = ci;
4       Thread.CurrentThread.CurrentUICulture = ci;

二、使用资源字典文件

这种方式的实现相对较为丰富,即可实现新增支持语言无需重新编译,也可实现程序运行中切换语言(参见本文实现动态切换程序显示语言),以下是常用实现方式。

1. 创建资源字典StringResource.xaml,包含需要支持多国语言的字符串

 1 <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 2                     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 3                     xmlns:sys="clr-namespace:System;assembly=mscorlib">
 4     <sys:String x:Key="WinTitle">MainWindow</sys:String>
 5     <sys:String x:Key="TblText">Support multi language demo.</sys:String>
 6     <sys:String x:Key="BtnOK">OK</sys:String>
 7     <sys:String x:Key="HdNo">No.</sys:String>
 8     <sys:String x:Key="HdName">Name</sys:String>
 9     <sys:String x:Key="HdGender">Gender</sys:String>
10     <sys:String x:Key="HdDept">Dept</sys:String>
11     <sys:String x:Key="HdEmail">Email</sys:String>
12     <sys:String x:Key="HdTel">Tel</sys:String>
13     <sys:String x:Key="MsgShowTime">Now time is:{0}</sys:String>
14 </ResourceDictionary>

2. 在app.xaml中使用MergedDictionary

 1 <Application x:Class="LocalizationDemo.App"
 2              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4              StartupUri="MainWindow.xaml" Exit="Application_Exit">
 5     <Application.Resources>
 6         <ResourceDictionary>
 7             <ResourceDictionary.MergedDictionaries>
 8                 <ResourceDictionary Source="Resources\StringResource.xaml" />
 9                 <ResourceDictionary Source="Resources\StringResource.zh-CN.xaml" />
10             </ResourceDictionary.MergedDictionaries>
11         </ResourceDictionary>
12     </Application.Resources>
13 </Application>

3. 在程序中使用资源字典中的字符串

  • .xaml文件,Text="{StaticResource TblText}"
  • .cs文件,string s = Application.Current.FindResource("MsgShowTime").ToString();

4. 复制StringResource.xaml命名为StringResource.zh-CN.xaml,key不变,value翻译为中文

 1 <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 2                     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 3                     xmlns:sys="clr-namespace:System;assembly=mscorlib">
 4     <sys:String x:Key="WinTitle">主窗体</sys:String>
 5     <sys:String x:Key="TblText">支持多国语言示例。</sys:String>
 6     <sys:String x:Key="BtnOK">确定</sys:String>
 7     <sys:String x:Key="HdNo">员工号</sys:String>
 8     <sys:String x:Key="HdName">姓名</sys:String>
 9     <sys:String x:Key="HdGender">性别</sys:String>
10     <sys:String x:Key="HdDept">部门</sys:String>
11     <sys:String x:Key="HdEmail">邮箱</sys:String>
12     <sys:String x:Key="HdTel">电话</sys:String>
13     <sys:String x:Key="MsgShowTime">现在时间是:{0}</sys:String>
14 </ResourceDictionary>

5. 在程序启动时根据当前区域加载对应的资源字典文件

 1             List<ResourceDictionary> dictionaryList = new List<ResourceDictionary>();
 2             foreach (ResourceDictionary dictionary in Application.Current.Resources.MergedDictionaries)
 3             {
 4                 dictionaryList.Add(dictionary);
 5             }
 6             string requestedCulture = string.Format(@"Resources\StringResource.{0}.xaml", Culture);
 7             ResourceDictionary resourceDictionary = dictionaryList.FirstOrDefault(d => d.Source.OriginalString.Equals(requestedCulture));
 8             if (resourceDictionary == null)
 9             {
10                 requestedCulture = @"Resources\StringResource.xaml";
11                 resourceDictionary = dictionaryList.FirstOrDefault(d => d.Source.OriginalString.Equals(requestedCulture));
12             }
13             if (resourceDictionary != null)
14             {
15                 Application.Current.Resources.MergedDictionaries.Remove(resourceDictionary);
16                 Application.Current.Resources.MergedDictionaries.Add(resourceDictionary);
17             }

6. 测试新增语言资源文件同"使用LocBaml工具"中step8

三、使用.resx资源文件

这种方式和Winform支持多国语言保持一致,相对较容易实现,新增支持语言需要重新编译程序,所有的.resx文件必须放在同一个主程序集中。

1. 添加字符串资源

在资源文件Resources.resx中添加字符串资源,并将访问修饰符设置为Public。

2. 在程序中使用资源文件

.xaml文件,引入名称空间:xmlns:props="clr-namespace:LocalizationDemo.Properties";使用方式:Text="{x:Static props:Resources.TblText}"

.cs文件,使用方式:string s = Properties.Resources.MsgShowTime;

3. 新增语言资源文件

以新增简体中文为例,复制资源文件Resources.resx,重命名为Resources.zh-CN.resx,将值翻译为中文保存。

4. 设置程序运行语言环境

1     LocalizationDemo.Properties.Resources.Culture = new CultureInfo("zh-CN");

四、实现动态切换程序显示语言

以上三种支持多国语言的解决方案都是在程序运行过程中不能变更语言的,要实现程序运行中动态切换语言就需要在UI设计使用DynamicResource,其中一种简单的实现是通过DynamicResource引用资源字典文件键值。

使用DynamicResource

具体实现方法和本文使用资源字典文件中步骤基本一致,只需将UI相关的.xaml文件中引用资源字典文件键值的StaticicResource改为DynamicResource,如下:

1     <TextBlock Height="23" TextWrapping="Wrap" Name="txtTips" Text="{StaticicResource TblText}" />
2     <!--StaticicResource改成DynamicResource,如下-->
3     <TextBlock Height="23" TextWrapping="Wrap" Name="txtTips" Text="{DynamicResource TblText}" />

非Visual Controls实现动态切换语言

需要注意的是,在WPF DataGrid中的DataGridColumn等控件不是Visual Controls,它们的Binding属性可以进行绑定,除此之外必须是Static静态的,也就是我们可以通过创建静态的样式资源,在这些样式资源中包含动态内容,然后在像DataGridColumn这样的控件中引用静态的样式资源就可以了,实现如下:

  • 静态样式资源包含动态内容
1     <Window.Resources>
2         <Style x:Key="HeaderNoStyle" TargetType="{x:Type DataGridColumnHeader}">
3             <Setter Property="Content" Value="{DynamicResource HdNo}" />
4     </Window.Resources>
  • DataGridColumn引用静态的样式资源
1     <DataGridTextColumn HeaderStyle="{StaticResource HeaderNoStyle}" Width="auto" Binding="{Binding No}"/>

附:实现MessageBox支持多语言

另外,和其他元素不同的是,MessageBox的确定(OK),是(Yes),否(NO)等按钮是直接调用系统Win32 API,MessageBox按钮当前显示哪种语言文本是由Windows操作系统安装的默认语言决定,而与其他无关。为了解决这一问题需要实现设置自定义系统MessageBox按钮文本,MessageBoxManager能够实现这一需求,更多内容请参见Localizing SystemMessageBox一文。另外一种解决办法就是自定义替代MessageBox功能的Windows窗体。

如何使用MessageBoxManager

      //设置OK按钮显示文本
      MessageBoxManager.OK = "确定啊,亲";
      //注册MessageBoxManager
      MessageBoxManager.Register();
      //正常使用MessageBox
      MessageBox.Show("你懂的...");
      //取消注册MessageBoxManager
      MessageBoxManager.Unregister();

猛击这里下载源代码

效果如下图:

目录
相关文章
|
前端开发 Ubuntu Linux
【.NET6+Avalonia】开发支持跨平台的仿WPF应用程序以及基于ubuntu系统的演示
随着跨平台越来越流行,.net core支持跨平台至今也有好几年的光景了。但是目前基于.net的跨平台,大多数还是在使用B/S架构的跨平台上;至于C/S架构,大部分人可能会选择QT进行开发,或者很早之前还有一款Mono可以支持.NET开发者进行开发跨平台应用。
1114 0
【.NET6+Avalonia】开发支持跨平台的仿WPF应用程序以及基于ubuntu系统的演示
|
3月前
|
C# 开发者 Windows
WPF 应用程序开发:一分钟入门
本文介绍 Windows Presentation Foundation (WPF),这是一种用于构建高质量、可缩放的 Windows 桌面应用程序的框架,支持 XAML 语言,方便 UI 设计与逻辑分离。文章涵盖 WPF 基础概念、代码示例,并深入探讨常见问题及解决方案,包括数据绑定、控件样式与模板、布局管理等方面,帮助开发者高效掌握 WPF 开发技巧。
174 65
|
4月前
|
前端开发 C# 开发者
WPF开发者必读:MVVM模式实战,轻松构建可维护的应用程序,让你的代码更上一层楼!
【8月更文挑战第31天】在WPF应用程序开发中,MVVM(Model-View-ViewModel)模式通过分离关注点,提高了代码的可维护性和可扩展性。本文详细介绍了MVVM模式的三个核心组件:Model(数据模型)、View(用户界面)和ViewModel(处理数据绑定与逻辑),并通过示例代码展示了如何在WPF项目中实现MVVM模式。通过这种模式,开发者可以更高效地构建桌面应用程序。希望本文能帮助你在WPF开发中更好地应用MVVM模式。
260 1
|
4月前
|
C# 微服务 Windows
模块化革命:揭秘WPF与微服务架构的完美融合——从单一职责原则到事件聚合器模式,构建高度解耦与可扩展的应用程序
【8月更文挑战第31天】本文探讨了如何在Windows Presentation Foundation(WPF)应用中借鉴微服务架构思想,实现模块化设计。通过将WPF应用分解为独立的功能模块,并利用事件聚合器实现模块间解耦通信,可以有效提升开发效率和系统可维护性。文中还提供了具体示例代码,展示了如何使用事件聚合器进行模块间通信,以及如何利用依赖注入进一步提高模块解耦程度。此方法不仅有助于简化复杂度,还能使应用更加灵活易扩展。
112 0
|
4月前
|
测试技术 C# 开发者
“代码守护者:详解WPF开发中的单元测试策略与实践——从选择测试框架到编写模拟对象,全方位保障你的应用程序质量”
【8月更文挑战第31天】单元测试是确保软件质量的关键实践,尤其在复杂的WPF应用中更为重要。通过为每个小模块编写独立测试用例,可以验证代码的功能正确性并在早期发现错误。本文将介绍如何在WPF项目中引入单元测试,并通过具体示例演示其实施过程。首先选择合适的测试框架如NUnit或xUnit.net,并利用Moq模拟框架隔离外部依赖。接着,通过一个简单的WPF应用程序示例,展示如何模拟`IUserRepository`接口并验证`MainViewModel`加载用户数据的正确性。这有助于确保代码质量和未来的重构与扩展。
116 0
|
4月前
|
C# 开发者 Windows
震撼发布:全面解析WPF中的打印功能——从基础设置到高级定制,带你一步步实现直接打印文档的完整流程,让你的WPF应用程序瞬间升级,掌握这一技能,轻松应对各种打印需求,彻底告别打印难题!
【8月更文挑战第31天】打印功能在许多WPF应用中不可或缺,尤其在需要生成纸质文档时。WPF提供了强大的打印支持,通过`PrintDialog`等类简化了打印集成。本文将详细介绍如何在WPF应用中实现直接打印文档的功能,并通过具体示例代码展示其实现过程。
411 0
|
4月前
|
开发者 C# 自然语言处理
WPF开发者必读:掌握多语言应用程序开发秘籍,带你玩转WPF国际化支持!
【8月更文挑战第31天】随着全球化的加速,开发多语言应用程序成为趋势。WPF作为一种强大的图形界面技术,提供了优秀的国际化支持,包括资源文件存储、本地化处理及用户界面元素本地化。本文将介绍WPF国际化的实现方法,通过示例代码展示如何创建和绑定资源文件,并设置应用程序语言环境,帮助开发者轻松实现多语言应用开发,满足不同地区用户的需求。
86 0
|
4月前
|
开发者 C# UED
WPF多窗口应用程序开发秘籍:掌握窗口创建、通信与管理技巧,轻松实现高效多窗口协作!
【8月更文挑战第31天】在WPF应用开发中,多窗口设计能显著提升用户体验与工作效率。本文详述了创建新窗口的多种方法,包括直接实例化`Window`类、利用`Application.Current.MainWindow`及自定义方法。针对窗口间通信,介绍了`Messenger`类、`DataContext`共享及`Application`类的应用。此外,还探讨了布局控件与窗口管理技术,如`StackPanel`与`DockPanel`的使用,并提供了示例代码展示如何结合`Messenger`类实现窗口间的消息传递。总结了多窗口应用的设计要点,为开发者提供了实用指南。
297 0
|
4月前
|
C# 前端开发 UED
WPF数据验证实战:内置控件与自定义规则,带你玩转前端数据验证,让你的应用程序更上一层楼!
【8月更文挑战第31天】在WPF应用开发中,数据验证是确保输入正确性的关键环节。前端验证能及时发现错误,提升用户体验和程序可靠性。本文对比了几种常用的WPF数据验证方法,并通过示例展示了如何使用内置验证控件(如`TextBox`)及自定义验证规则实现有效验证。内置控件结合`Validation`类可快速实现简单验证;自定义规则则提供了更灵活的复杂逻辑支持。希望本文能帮助开发者更好地进行WPF数据验证。
154 0
|
4月前
|
开发者 C# Windows
WPF布局大揭秘:掌握布局技巧,轻松创建响应式用户界面,让你的应用程序更上一层楼!
【8月更文挑战第31天】在现代软件开发中,响应式用户界面至关重要。WPF(Windows Presentation Foundation)作为.NET框架的一部分,提供了丰富的布局控件和机制,便于创建可自动调整的UI。本文介绍WPF布局的基础概念与实现方法,包括`StackPanel`、`DockPanel`、`Grid`等控件的使用,并通过示例代码展示如何构建响应式布局。了解这些技巧有助于开发者优化用户体验,适应不同设备和屏幕尺寸。
130 0