应用国际化多语言化实现方法
主要介绍各种应用如何使用资源文件resx或者ResourceDictionary实现多语言化,以及各种方法之间的区别。
背景
如果程序需要国际化或者说多语言化,不管是Web程序、窗体程序还是移动应用程序一般我们都会使用资源文件来定义,通过切换线程的使用语言来实现。
定义的多语言文件:
编译之后各个资源文件内容变成独立文件夹,如下图:
争对WPF,UWP,Xamarin等应用其实除了资源文件,还有ResourceDictionary可以选择。那这些方法如何使用?
资源文件的语言切换方法
如果想手动切换语言,可以使用如下方法改变线程的使用区域。
Thread.CurrentThread.CurrentCulture = new CultureInfo("zh-CH"); Thread.CurrentThread.CurrentUICulture = new CultureInfo("zh-CH");
还有一种就是切换系统语言与区域。
资源文件使用方法一
我个人推荐创建类库专门放资源文件,好处:
- 除UI层之外的其他层也可以使用,比如log。
- 后台调用如同使用Const常量。
特殊修改点:
添加资源文件之后需要修改资源文件的属性为Public。
MSGResource.Designer.cs文件中的类属性也变成了Public,如果是Internal外部类库将无法访问。
备注:如果想输入换行按Shift+Enter。不能直接使用【\n】。
Xaml调用方法(画线部分):
<Window x:Class="ResourceDemo.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:ResourceDemo" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:res="clr-namespace:Data.Resources;assembly=Data.Resources" Title="MainWindow" Width="800" Height="450" mc:Ignorable="d"> <Grid> <TextBlock Width="200" Height="200" Text="{x:Static res:MSGResource.I0001}" /> </Grid> </Window>
后台代码调用方法:
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); lblTest.Text = Data.Resources.MSGResource.I0001; } }
资源文件使用方法二(系统默认方式)
WPF来说,新建项目会默认生成一个资源文件放在Properties下面,你可以更改名字并添加新的项目。坏处就是没法给其他层共享。
修改成如下:
Xaml调用方法:
<Window x:Class="ResourceDemo.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:ResourceDemo" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:res="clr-namespace:ResourceDemo.Properties" Title="MainWindow" Width="800" Height="450" mc:Ignorable="d"> <Grid> <TextBlock x:Name="lblTest" Width="200" Height="200" Text="{x:Static res:MSGResources.I0001}" /> </Grid> </Window>
后台代码调用方法:
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); lblTest.Text = Properties.MSGResources.I0001; } }
ResourceDictionary方式(WPF,UWP等特有)
ResourceDictionary方式可以一次性声明,全局使用。
唯独键值维护和语言切换比较麻烦。
ResourceDictionary内容:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:ResourceDemo.Resources" xmlns:system="clr-namespace:System;assembly=mscorlib"> <system:String x:Key="W0001">Warning message.</system:String> <system:String x:Key="E0001">Error message.</system:String> <system:String x:Key="I0001">Info message.</system:String> </ResourceDictionary>
App.xaml全局声明:
<Application x:Class="ResourceDemo.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:ResourceDemo" StartupUri="MainWindow.xaml"> <Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="Resources/MSGDictionary.xaml" /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources> </Application>
Xaml侧调用:
<Window x:Class="ResourceDemo.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:ResourceDemo" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" Title="MainWindow" Width="800" Height="450" mc:Ignorable="d"> <Grid> <TextBlock x:Name="lblTest" Width="200" Height="200" Text="{StaticResource I0001}" /> </Grid> </Window>
后台调用:
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); lblTest.Text = Application.Current.FindResource("W0001").ToString(); } }
语言切换方法:
private void Button_Click(object sender, RoutedEventArgs e) { Thread.CurrentThread.CurrentCulture = new CultureInfo("zh-CN"); Thread.CurrentThread.CurrentUICulture = new CultureInfo("zh-CN"); Application.Current.Resources.MergedDictionaries.RemoveAt(0); Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary { Source = new Uri("Resources/MSGDictionary.zh-CN.xaml", UriKind.Relative) }); }