WPF: 本地化(Localization) 實現


本文將討論在WPF中一種較為方便的本地化方法。

由於在項目中要實現本地化,所以我在網上查找相關的解決方案。通過一系列調研,發現實現本地化的方法主要有以下三種:

  1. 通過編譯項目以設置 x:Uid 並使用 LocBaml 工具實現;
  2. 通過 DynamicResource 實現;
  3. 通過 Resx 文件實現

其中第一種是官方介紹的方法,考慮到實現步驟略為復雜,所以直接忽略;

第二種方式的實現,主要是在程序中添加 Resource Dictionary 類型的文件,並在其中放入本地化資源字符串;在 XAML 代碼中,直接使用 {DynamicResource XXXX} 來實現;這種方法比較方便,不過它也有兩個缺點:

  • 在 XAML 中,引用 DynamicResource 的屬性必須為依賴屬性,否則會出錯;
  • 在 C# 代碼中引用稍微有點麻煩,需要從 Resource Dictionary 中獲取並轉化為字符串

其中第一點可以說是致命缺點,我曾在項目中添加了一個第三方控件,其 Header 屬性並不是依賴屬性,所以不能使用這種方式;不是依賴屬性,當然,也就更不能使用綁定(Binding)來設置了。

所以,之后嘗試了第三種方式——使用 resx 文件,事實上,這是一種比較傳統的、且普遍的方式,說它傳統,是因為在 WinForm 中就可以這么做;說它普遍,是因為在 ASP.net MVC 中也可以這么做;並且,在 UWP 中的實現方式也與此有點類似。可以說,基本上基於 .NET 的各個平台都是以這種或類似這種方式來實現本地化的。並且,事件證明,這種方式的確是非常合適的,也很好用,在 XAML 代碼和 C# 代碼中均可以非常方便的使用。 

使用 ResX 文件實現 

它的操作步驟大概如下:

1. 創建一個 WPF 項目;

2. 在主窗口中添加幾個需要本地化其內容的控件,如 TextBlock、Button等;

3. 展示此項目的 Properties 文件夾,這里已經有一個默認的 Resources.resx,在其中添加本地化字符串;

4. 將其復制,並粘貼到當前位置,將新文件改名為 Resources.en-US.resx,並修改其中的本地化字符串為對應的語言值;

說明:這里我們添加了對英語語言的本地化,至於支持哪些語言的本地化,可以參考這篇文章 Supported languages,關於語言匹配可參考這篇文章 Manage language and region,盡管這兩篇文章是針對 UWP 的,不過原則上,對於 WPF 也是適用的;

5. 將上述兩個 resx 文件的 Access Modifier 修改為 Public,默認值是 Internal;如下圖:

 接下來就是如何使用了:

6. 在 Xaml 中添加命名空間引用:

xmlns:loc="clr-namespace:WpfLocalizationTest.Properties"

7. 使用 {x:Static} 標記引用資源,如下:

<TextBlock Text="{x:Static loc:Resources.Main_Menu_Home}" />

8. 如果需要在代碼中引用,也非常簡單:

var homePage = Properties.Resources.Main_Menu_Home;

經測試,這種方式也支持 IntelliSense(智能提示),如下圖:

如果你沒看到智能提示,可以先編譯項目。

此時,有兩種方式可以測試本地化效果,第一種方式是在控制面板中改變操作系統的語言,第二種方式是通過代碼改變 CurrentUICulture;這里我們使用后者,在 App.xaml.cs 中添加如下代碼:

        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
            Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-US");
        }

運行后就可以看到測試結果了。 

在大型項目中使用 

上面是在 Demo 中展示如何本地化應用,那么在大型項目中是如何來應用這種方式呢?以下簡單介紹一下,可以供參考:

1. 在解決方案中創建一個類庫項目(或在已有項目中進行后續操作),此項目的用途主要是作資源用;

2. 在其中創建 Localization 文件夾,在這個文件夾下可以再創建針對各個模塊的子文件夾,然后在此創建 resx 文件、添加本地化字符串並復制。文件結構如下:

3. 要在主程序中使用,方式和我們在 Demo 中提到的是一樣的。首先在主程序項目中添加對新創建項目的引用,然后在 XAML 中添加命名空間和相關代碼:

xmlns:loc2="clr-namespace:App.Resources.Localization.MainModule;assembly=App.Resources"
<Button Margin="5" Padding="5" Content="{x:Static loc2:Resources.Main_New}" />
<Button Margin="5" Padding="5" Content="{x:Static loc2:Resources.Main_Open}" />

更方便的方式 

如果軟件中有大量的文本需要本地化,那么在 resx 文件中的資源項將會非常多,這時,要在兩個甚至更多資源文件中添加、刪除、對比、檢查項目時,將會非常困難。有沒有更方便的方法呢?這里推薦一個 VS Extension: ResX Manager

它可以非常方便地管理當前解決方案中的 Resx 文件以及其中的資源項,安裝后,在 VS 中工具菜單中可以打開,界面如下:

需要注意的是,如果要添加新資源項時,必須在左側僅選擇目標資源文件。它的具體用法,不屬於本文討論的范圍,如果大家有需要了解,可以搜索相關教程。總之,通過這個插件,可以非常方便地創建、刪除、管理本地化文本。

總結

所以,通過本文所提出的 Resx 文件本地化方案再加 ResXManager 擴展,你就可以方便地在你的 WPF項目中實現本地化了。如果您有更好的建議或意見,請留言交流。

 

參考文章:

WPF Globalization and Localization Overview

How to: Localize an Application

Supported languages

Manage language and region

WPF Localization

Localizing WPF Applications using Locbaml

 

源碼下載


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM