WPF多國語系(Localization)

何謂多國語系

一個專案若需同時應付不同國籍的使用者, 在早期就需出多個版本, 更改每個版本顯示的文字. 但從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會隨著字典而變化. 相對的, 也比較耗系統資源

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *