應用國際化多語言化實現方法
阿新 • • 發佈:2018-12-19
背景
如果程式需要國際化或者說多語言化,不管是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外部類庫將無法訪問。
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) }); }