背景
如果程序需要國際化或者說多語言化,不管是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) }); }