1. 程式人生 > 其它 >WPF: 本地化(Localization) 實現 WPF: 本地化(Localization) 實現

WPF: 本地化(Localization) 實現 WPF: 本地化(Localization) 實現

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中一種較為方便的本地化方法。

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

  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專案中實現本地化了。如果您有更好的建議或意見,請留言交流。