何謂多國語系
一個專案若需同時應付不同國籍的使用者, 在早期就需出多個版本, 更改每個版本顯示的文字. 但從WPF開始, 就支援此種需求了. 可依使用者的作業系統, 自動更改顯示的語系.
當然, 如果使用Windows Form的話,也可以在 .resx 中定義各語系的文字. 再使用ResourceManager 依據 CultureInfo 的值進行切換. 但WPF 的 XAML 是找不到 .resx類型中的資源. 所以此種作法必需完全拋棄.
建立資源字典(ResourceDictionary)
不同語系的文字, 可以存放在資源字典裏. 不過語系可能相當多, 所以建議先建立一個資料夾 Lang 專門用來存放不同的語系檔案.
然後在Lang按右鍵/加入/新增項目, 再選取 資源字典(WPF), 檔名必需依CultureInfo的規定來命名, 英文語系就設定為en-US.xaml, 繁體中文設定為 zh-TW.xaml, 簡体中文設為zh-CN.xaml.
底下為en-US.xaml 內容, 紅色部份為需要手動寫入的地方. 因外需注意的是, en-US.xaml 的屬性視窗中, 把建置動作(BuildAction)設定為Page. 這會就會被編譯進入應用程式中, 變成一個默認的語系, 也就是在沒有相對應的語系中, 默認使用英文.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:MyProject" xmlns:sys="clr-namespace:System;assembly=mscorlib"> <sys:String x:Key="btnOk"> OK </sys:String> </ResourceDictionary>
下面為zh-TW.xaml的程式碼. 此文件屬性視窗中的建置動作請設定為內容, 複製到輸出目錄的屬性請選擇 “有更新時才複製”(if new). 如此就會把此檔 copy 到安裝目錄下的 Lang 資料夾. 日後若需更加其他語系的話, 只要在此目錄下新增 xaml 檔案即可, 不需重新編譯程式碼
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:MyProject" xmlns:sys="clr-namespace:System;assembly=mscorlib"> <sys:String x:Key="btnOk"> 確定 </sys:String> </ResourceDictionary>
登入資源字典
在app.xaml檔案中, 需增加資源字典的目錄及預設檔案, 如下所示, 紅色的部份為需要增加的代碼.
當登入正確後, 就可以在xaml 中使用資源字典了. 如
<Button Content=”{DynamicResource btnOk}”/>
<Application x:Class="MyProject.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:Dant2" StartupUri="MainWindow.xaml"> <Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source = "Lang\en-US.xaml"/> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources> </Application>
啟動時加載本地語系
上述設定好後, 執行App還是為預設的英文語系. 若希望隨系統的語系自動變更, 必需在App.xaml.cs加入如下代碼
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
LoadLanguage();
}
private void LoadLanguage()
{
CultureInfo currentCultureInfo = CultureInfo.CurrentCulture;
ResourceDictionary langRd = null;
try
{
langRd =Application.LoadComponent(
new Uri(@"Lang\" + currentCultureInfo.Name + ".xaml ", UriKind.Relative)) as ResourceDictionary;
}
catch
{
}
if (langRd != null)
{
if (this.Resources.MergedDictionaries.Count > 0)
{
this.Resources.MergedDictionaries.Clear();
}
this.Resources.MergedDictionaries.Add(langRd);
}
}
}
代碼中使用
在C#中使用字典資源, 有二種方式, 一種是靜態調用, 一種是動態調用. 先列出調用方式如下
lblTitle.Content = FindResource(“lblTitle”).ToString();
lblTitle.SetResourceReference(Label.ContentProperty, “lblTitle”);
第一種方式為靜態調用. 當資源字典變更成其他語系後, Title並不會隨著變化
第二種方式為動態調用, Title會隨著字典而變化. 相對的, 也比較耗系統資源