怎樣實現WPF Prism Module的國際化和本地化?

来源:https://www.cnblogs.com/Dotnet9-com/archive/2020/04/21/12742046.html
-Advertisement-
Play Games

怎樣實現WPF Prism Module的國際化和本地化? "English" | 簡體中文 上一篇有簡單介紹主工程的國際化,使用的資源字典(XAML)實現的。 這幾天我添加了幾個Prism模塊(Module),發現子模塊使用資源字典的方式實現國際化和本地化不好做,沒有找到比較好的參考文章,所以換了 ...


怎樣實現WPF Prism Module的國際化和本地化?

English | 簡體中文

上一篇有簡單介紹主工程的國際化,使用的資源字典(XAML)實現的。
這幾天我添加了幾個Prism模塊(Module),發現子模塊使用資源字典的方式實現國際化和本地化不好做,沒有找到比較好的參考文章,所以換了一種方式,使用資源文件實現了。

讓WPF項目走上國際化路線

一、本文概述

子模塊的國際化和本地化要求:

    1. 各模塊需要有自己單獨的語言文件。
    1. 在主工程中動態切換語言時,子模塊也需要跟著切換。
    1. 使用了Prism實現模塊化框架,即要求主工程與各子模塊不能有引用關係,即松耦合,不能直接在主工程中切換子模塊的語言文件。

基於上面的要求,我嘗試在各模塊(Module)中也定義了語言文件(XAML),主窗體切換語言時,載入模塊語言文件老是提示不存在對應的資源字典文件,我惱火呀,後面還是參考“Accelerider.Windows”國際化的方式,使用資源文件實現本地化和國際化了,不糾結Xaml的方式了,唉。

此路不通,我換條路走

下麵是修改後的效果:

和上一版異同:

    1. 標題欄國際化無變化,只是文字綁定換了種方式,實現效果一致。
    1. 左側添加了三個子模塊(Home\Client\Server),使用Prism動態載入的,並且跟隨主工程主窗體語言切換而切換語言。

下麵簡單介紹怎麼創建模塊,以及主窗體和模塊國際化怎麼做的,真的是很簡單的介紹,具體的實現可以拉代碼看看。

跌到,爬起來,繼續趟坑

二、 添加三個Prism模塊(Module)

可安裝Prism模板,快速創建模塊工程,當然手工創建.Net Core工程也是可以的,就是多了幾個步驟而已(需要用Nuget安裝Prism.Wpf包(7.2.0.1422)),我使用得的Prism模板快速創建的。

2.1 創建模塊之前的準備工作

VS2019下載Prism模板

下載上圖搜索到的Prism模板,重啟VS,它會自動安裝,新建項目時,就有Prism模塊模板選擇了:

Prism模板工程

註意要選擇.NET Core 3的版本,因為我是使用.NET Core創建的WPF項目。

2.2 創建模塊

下麵是已經創建好的三個模塊工程截圖:

目前三個模塊文件組織結構類似:

  • I18nResources:資源文件夾,放3個語言資源文件和一個T4模板文件(用於引用語言Key),其中T4模板文件在3個模塊和主工程中定義是一樣的,具體可從github下載源碼查看。
  • Views放置視圖文件,現在只使用到了主工程主窗體中顯示的TabItem視圖,即MainTabItem.xaml,繼承自TabItem。
  • xxxxModule.cs:prism模板定義文件,prism發現模塊使用。

三個模塊關鍵點需要註意:

    1. 編輯模塊工程文件,修改模塊文件輸出目錄:
// 省略部分代碼,下麵這一行設置為False,代表輸出目錄不帶.NET Core版本信息
<AppendTargetFrameworkToOutputPath>Flase</AppendTargetFrameworkToOutputPath>
// 省略部分代碼,修改Debug與Release編譯輸出目錄,方便主工程統一載入模塊
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
  <OutputPath>..\Build\Debug\Modules</OutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
  <OutputPath>..\Build\Release\Modules</OutputPath>
</PropertyGroup>  
// 省略部分代碼
    1. XXXModule中需要將資源文件的ResourceManager引用添加到另一個庫中保存,待切換語言時需要使用,如在HomeModule的構造函數中添加代碼如下,只添加這一句代碼就好,模塊的國際化及本地化就算完事了:
I18nManager.Instance.Add(TerminalMACS.Home.I18nResources.UiResource.ResourceManager);
    1. XXXModule的RegisterTypes方法中註冊視圖"MainTabItem"到"RegionNames.MainTabRegion",主窗體使用"RegionNames.MainTabRegion"關聯模塊視圖顯示載入。
_regionManager.RegisterViewWithRegion(RegionNames.MainTabRegion, typeof(MainTabItem));
    1. UI控制項國際化文字綁定,其中markup使用的一個開源庫命名空間,後面會給出鏈接,本項目直接將該庫載入進瞭解決方案中;i18NResources:Language即T4模板文件生成的類,關聯文字翻譯的Key。綁定文字部分代碼如下:
<TextBlock Grid.Row="2" Text="{markup:I18n {x:Static i18NResources:Language.MainTabItm_Header}}"

三、 主工程

主工程目錄組織結構如下:

3.1 動態載入Prism模塊

配置載入3個模塊的關鍵代碼在App.xaml.cs文件中,看上面的代碼,我將三個模塊輸出到了Modules目錄下,主工程直接載入此目錄即可,其他載入方式還有使用配置文件等,可以參考Prism官方例子,文末給出鏈接:

protected override IModuleCatalog CreateModuleCatalog()
{
    string modulePath = @".\Modules";
    if (!Directory.Exists(modulePath))
    {
        Directory.CreateDirectory(modulePath);
    }
    return new DirectoryModuleCatalog() { ModulePath = modulePath };
}

主窗體顯示子模塊註冊的TabItem視圖,prism:RegionManager.RegionName即在各子模塊中註冊過的區域字元串,他與模塊對應的TabItem視圖關聯,代碼如下:

<TabControl Grid.ColumnSpan="2" SelectedIndex="0"
    Style="{StaticResource MainTabControlStyle}" 
    ItemContainerStyle="{StaticResource MainTabItemStyle}"
    prism:RegionManager.RegionName="{x:Static ui:RegionNames.MainTabRegion}"/>

主窗體以TabControl的控制項形式展示子模塊視圖:

子模塊的TabItem視圖

主工程要能正常載入子模塊,主工程的工程文件也需要修改其輸出目錄:

// 省略部分代碼,下麵這一行設置為False,代表輸出目錄不帶.NET Core版本信息
<AppendTargetFrameworkToOutputPath>Flase</AppendTargetFrameworkToOutputPath>
// 省略部分代碼,修改Debug與Release編譯輸出目錄,方便主工程統一載入模塊
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
  <OutputPath>..\Build\Debug</OutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
  <OutputPath>..\Build\Release</OutputPath>
</PropertyGroup>  
// 省略部分代碼

3.2 修改語言文件格式

刪除了原有的XAML語言文件,替換為resx的資源文件,和三個模塊的資源文件類型類似,下麵是主工程的資源文件:

資源文件作為語言文件使用

替換成資源文件,編輯是要比XAML文件要方便點,起初是有考慮使用資源文件實現國際化的,作死想嘗試XAML文件。

折騰是可以漲姿勢的

3.3 語言切換核心代碼

動態切換語言的關鍵代碼改為:

public static void SetLanguage(string language = "")
{
    if (string.IsNullOrWhiteSpace(language))
    {
        language = ConfigHelper.ReadKey(KEY_OF_LANGUAGE);
        if (string.IsNullOrWhiteSpace(language))
        {
            language = System.Globalization.CultureInfo.CurrentCulture.ToString();
        }
    }

    ConfigHelper.SetKey(KEY_OF_LANGUAGE, language);
    _lastLanguage = language;

    var culture = new System.Globalization.CultureInfo(language);
    I18nManager.Instance.CurrentUICulture = culture;
}

核心的語言切換代碼是最後一句,不詳細說了,解決方案中有庫、有源碼:

I18nManager.Instance.CurrentUICulture = culture;

四. 源碼

關於

五. 參考資料


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前言 創建型:單例模式,工廠模式,建造者模式,原型模式 結構型:橋接模式,代理模式,裝飾器模式,適配器模式,門面模式,組合模式,享元模式 行為型:觀察者模式,模板模式,策略模式,責任鏈模式,狀態模式,迭代器模式,訪問者模式 介紹 在工作中,我們經常要和Servlet Filter,Spring MV ...
  • 輸入三角形的三邊,判斷是否能構成三角形。若能構成輸出yes,否則輸出no。輸入格式:在一行中直接輸入3個整數,3個整數之間各用一個空格間隔,沒有其他任何附加字元。輸出格式:直接輸出yes或no,沒有其他任何附加字元。代碼如下:#!/usr/bin/python# -*- coding: utf-8 ... ...
  • Java IO流學習總結一:輸入輸出流 轉載請標明出處:http://blog.csdn.net/zhaoyanjun6/article/details/54292148本文出自【趙彥軍的博客】 感謝博主,感謝分享 Java流類圖結構: 流的概念和作用: 流是一組有順序的,有起點和終點的位元組集合,是 ...
  • 單例模式(Singleton Pattern)是一種常用的軟體設計模式,該模式的主要目的是確保某一個類只有一個實例存在。當你希望在整個系統中,某個類只能出現一個實例時,單例對象就能派上用場。 比如,某個伺服器程式的配置信息存放在一個文件中,客戶端通過一個 AppConfig 的類來讀取配置文件的信息 ...
  • 1、雙下方法 定義:雙下方法是特殊方法,它是解釋器提供的 由雙下劃線加方法名加雙下劃線 方法名的具有特殊意義的方法,雙下方法主要是python源碼程式員使用的,我們在開發中儘量不要使用雙下方法,但是深入研究雙下方法,更有益於我們閱讀源碼。 (1)調用:不同的雙下方法有不同的觸發方式, __ len_ ...
  • 在面向對象的中,類與類之間存在三種關係:依賴關係、組合關係、繼承關係。 1、依賴關係: 將一個類的類名或對象當做參數傳遞給另一個函數被使用的關係就是依賴關係 2、組合關係: 將一個類的對象封裝到另一個類的對象的屬性中,就叫組合 3、繼承關係 (1)什麼是面向對象的繼承 繼承(英語:inheritan ...
  • 版權聲明:本文為CSDN博主「Crystal7003」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。原文鏈接:https://blog.csdn.net/crystal7003/article/details/80043283 感謝博主分享 集合包含Colle ...
  • 以前在 Servlet 中獲取某個指定的 Cookie 的值使用 來獲得所有 Cookie 的值,然後再遍歷。 在 SpringMVC 中可以直接使用 註解來獲得指定的 Cookie 的值。 @CookieValue 中的參數有三個,其中一個 value 用來指定 Cookie 中的參數名,其他參數 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...