[連載]《C#通訊(串口和網路)框架的設計與實現》- 13.中英文版本切換設計

来源:http://www.cnblogs.com/lsjwq/archive/2016/01/06/5104412.html
-Advertisement-
Play Games

目 錄第十三章 中英文版本切換設計... 213.1 不用自帶的資源文件的理由... 213.2 配置文件... 213.3 語言管理類... 313.4 應用管理類... 1213.5 小結... 12第十三章 中英文版本切換設計13.1 不用自帶的資源文件的理由 可以利用resx資源文件進行多語...


目       錄

第十三章     中英文版本切換設計... 2

13.1        不用自帶的資源文件的理由... 2

13.2        配置文件... 2

13.3        語言管理類... 3

13.4        應用管理類... 12

13.5        小結... 12

 

第十三章      中英文版本切換設計

13.1     不用自帶的資源文件的理由

     可以利用resx資源文件進行多語言設計,resx文件本身是kv類型的資源文件,設計好資源文件後,啟動軟體時可以通過CurrentCulture屬性設置要顯示的語言。實現代碼如下:

//設置成英文版本

Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("en-us");

     但是,軟體涉及到多線程、線程池、非同步等應用的時候,當前線程設置了英文版本,其他線程還是預設的語言文化,例如:主線程設置了en-US,但是新建線程和其他已經存在的線程還是zh-CN,如果各部分UI不在同一線程更新的話,語言文化的設置是不一樣的,所以沒有辦法實現統一的語言顯示。

     那麼,可不可以通過進程獲得所有線程信息,統一進行設置語言文化信息呢,的確是一個很好的想法。但是,通過實踐證明這是行不能的,可能造反軟體異常退出。為什麼會出現這個現象呢?我猜想,一個進程中不僅包括自定義的線程,還存在系統級的線程,這樣操作是一件危險的事。

    難道就沒有辦法實現了嗎?人不可能被尿憋死。在.NET 4.5中就簡單多了,直接使用System.Globalization命名空間內CultureInfo類型的 DefaultThreadCurrentCulture和DefaultThreadCurrentUICulture屬性。設置好後,每一個新線程的 CurrentUICulture和CurrentCulture屬性都會和這個值保持一致的。CultureInfo類具體怎麼實現的,還沒有研究過。

    為了相容XP操作系統,還在使用.NET4.0的框架。相信也可以實現CultureInfo類的功能,但是不如自己設計一套語言版本方案更直接、更省時間。有時間的情況下可以研究一下CultureInfo類的實現。

13.2     配置文件

     先設計語言配置文件,文件格式採用XML,存儲方式採用KV的方式,文件命名可以自定義,例如:cn.xml、en.xml。如下圖:

 

     Key的定義有兩種方式,第一種:窗體命名.控制項命名,可以對窗體的控制項統一改變顯示的語言信息。第二種:直接定義關鍵字,可以對提示信息、狀態信息等單獨詞條改變顯示的語言信息。Value就是最終要顯示語言的具體內容,完全自定義。

13.3     語言管理類

  1. 定義一個詞條對應的可序列化的類。代碼如下:
[Serializable]
public class CultureItem
{
       /// <summary>
       /// 控制項的級聯ID,中間用"."分隔
       /// </summary>
       [XmlAttribute]
       public string Key { set; get; }

       /// <summary>
       /// 中文或英文描述
       /// </summary>
       [XmlAttribute]
       public string Value { set; get; }
}
  1. 定義一個設置語言屬性的枚舉。代碼如下:
public enum CultureLanguage
{
       [EnumDescription("中文")]
       Chinese,
       [EnumDescription("英文")]
       English
}
  1. 開發一個語言管理類庫,本質上是根據語言配置文件對Dictionary<string, string>字典緩存進行操作。實現代碼如下:
public class CultureMananger
{
       private static Dictionary<string, string> _dic = new Dictionary<string, string>();
       private static string _cnPath = Application.StartupPath + "\\SuperIO\\Language\\cn.xml";
       private static string _enPath = Application.StartupPath + "\\SuperIO\\Language\\en.xml";
       private static object SyncObject = new object();

       /// <summary>
       /// 載入語言文件到緩存中
       /// </summary>
       public static void LoadCulture()
       {
              lock (SyncObject)
              {
                     if (IsLanguage)
                     {
                            try
                            {
                                   _dic.Clear();
                                  string path = String.Empty;
                                   if (Language == CultureLanguage.Chinese)
                                   {
                                          path = _cnPath;
                                   }
                                   else if (Language == CultureLanguage.English)
                                   {
                                          path = _enPath;
                                   }
                                   if (File.Exists(path))
                                   {
                                          List<CultureItem> itemList =SerializeOperation.SerializeOperation.GetSerialize<List<CultureItem>>(path);
                                          foreach (CultureItem item in itemList)
                                          {
                                                 _dic.Add(item.Key, item.Value);
                                          }
                                   }
                            }
                            catch (Exception ex)
                            {
                                   GeneralLog.WriteLog(ex);
                            }
                     }
              }
       }
 
       /// <summary>
       /// 清除緩存中的語言信息
       /// </summary>
       public static void ClearCache()
       {
              lock (SyncObject)
              {
                     _dic.Clear();
              }
       }

       /// <summary>
       /// 設置和獲得語言類型屬性
       /// </summary>
       public static CultureLanguage Language
       {
              set
              {
                     if (GlobalProperty.GetInstance().Language != value)
                     {
                            GlobalProperty.GetInstance().Language = value;
                            GlobalProperty.GetInstance().Save();
                            LoadCulture();
                     }
              }
              get { return GlobalProperty.GetInstance().Language; }
       }

       /// <summary>
       /// 獲得詞條對應的描述信息
       /// </summary>
       /// <param name="formName">窗體名稱</param>
       /// <param name="field">詞條欄位</param>
       /// <returns>對應的描述信息</returns>
       public static string GetString(string formName, string field)
       {
              return GetString(String.Format("{0}.{1}", formName, field));
       }
 
       /// <summary>
       /// 獲得詞條對應的描述信息
       /// </summary>
       /// <param name="key">欄位的關鍵字</param>
       /// <returns></returns>
       public static string GetString(string key)
       {
              lock (SyncObject)
              {
                     if (IsLanguage)
                     {
                            string val = String.Empty;
                            if (_dic.ContainsKey(key))
                            {
                                   _dic.TryGetValue(key, out val);
                            }
                            return val;
                     }
                     else
                     {
                            return String.Empty;
                     }
              }
       }

       /// <summary>
       /// 應用窗體,改變語言顯示
       /// </summary>
       /// <param name="frm"></param>
       public static void ApplyResourcesForm(Form frm)
       {
              if (IsLanguage)
              {
                    string frmText = GetString(frm.Name);
                     if (!String.IsNullOrEmpty(frmText))
                     {
                            frm.Text = frmText;
                     }
                     ApplyControls(frm.Name, frm.Controls);
              }
       }
 
       /// <summary>
       /// 應用BarManager工具具,改變語言顯示
       /// </summary>
       /// <param name="name"></param>
       /// <param name="bar"></param>
       public static void AppResourceBarItem(string name, BarManager bar)
       {
              if (IsLanguage)
              {
                     string key = String.Empty;
                     foreach (BarItem item in bar.Items)
                     {
                            key = String.Format("{0}.{1}", name, item.Name);
                            string val = GetString(key);
                            if (!String.IsNullOrEmpty(val))
                            {
                                   item.Caption = val;
                            }
                     }
              }
       }

       /// <summary>
       /// 應用控制項,改變語言顯示
       /// /summary>
       /// <param name="name"></param>
       /// <param name="ctrls"></param>
       public static void ApplyControls(string name, Control.ControlCollection ctrls)
       {
              if (IsLanguage)
              {
                    foreach (Control ctrl in ctrls)
                     {
                            if (ctrl is MenuStrip) //MenuStrip StatusStrip
                            {
                                   ApplyMenuStrip(name, (MenuStrip) ctrl);
                            }
                            else if (ctrl is StatusStrip)
                            {
                                   ApplyStatusStrip(name, (StatusStrip) ctrl);
                            }
                            else if (ctrl is ListView)
                            {
                                   ApplyListView(name, (ListView) ctrl);
                            }
                            else
                            {
                                   ApplyControls(name, ctrl);
                            }

                            if (ctrl.HasChildren)
                            {
                                   ApplyControls(name, ctrl.Controls);
                            }
                     }
              }
       }

       internal static bool IsLanguage
       {
              get
              {
                     if (File.Exists(_cnPath) && File.Exists(_enPath))
                     {
                            return true;
                     }
                     else
                     {
                            return false;
                     }
              }
       }

       private static void ApplyControls(string name, Control ctrl)
       {
              string key = String.Format("{0}.{1}", name, ctrl.Name);
              string text = GetString(key);
              if (!String.IsNullOrEmpty(text))
              {
                     ctrl.Text = text;
              }
       }

       private static void ApplyMenuStrip(string name, MenuStrip menu)
       {
              foreach (ToolStripMenuItem item in menu.Items)
              {
                     ApplyMenuItem(name, item);
              }
       }

       private static void ApplyMenuItem(string name, ToolStripMenuItem item)
       {
              string key = String.Format("{0}.{1}", name, item.Name);
              string text = GetString(key);
              if (!String.IsNullOrEmpty(text))
              {
                     item.Text = text;
              }
              if (item.DropDownItems.Count > 0)
              {
                     foreach (ToolStripMenuItem subItem in item.DropDownItems)
                     {
                            ApplyMenuItem(name, subItem);
                     }
              }
       }
 
       private static void ApplyStatusStrip(string name, StatusStrip status)
       {
              string key = String.Empty;
              foreach (ToolStripItem item in status.Items)
              {
                     key = String.Format("{0}.{1}", name, item.Name);
                     string val= GetString(key);
                     if (!String.IsNullOrEmpty(val))
                     {
                            item.Text = val;
                     }
              }
       }
 
       private static void ApplyListView(string name, ListView lv)
       {
              string key = String.Empty;
              foreach (ColumnHeader header in lv.Columns)
              {
                     key = String.Format("{0}.{1}", name, header.Tag == null ? "" : header.Tag.ToString());
                     string val = GetString(key);
                     if (!String.IsNullOrEmpty(val))
                     {
                            header.Text = val;
                     }
              }
       }
}

 

13.4     應用管理類

     在軟體啟動時可以使用CultureMananger管理類,具體應用代碼如下:

CultureMananger.LoadCulture();
CultureMananger.ApplyControls("MainForm",this.Controls);
string state=CultureMananger.GetString("State.Normal");

13.5     小結

    這是一個小的工具組件,具有一定的通用性。

 

 

作者:唯笑志在

Email:[email protected]

QQ:504547114

.NET開發技術聯盟:54256083

文檔下載:http://pan.baidu.com/s/1pJ7lZWf

官方網址:http://www.bmpj.net


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

-Advertisement-
Play Games
更多相關文章
  • 五種I/O: 1)阻塞I/0 2)非阻塞I/O 3)I/O復用 4)事件(信號)驅動I/O 5)非同步I/O
  • 接著上一篇博客繼續Tomcat配置。3. 虛擬目錄映射虛擬目錄是與實際目錄相對應的,不是一個實際存在的目錄。配置虛擬目錄有兩點好處:1、 便於理解;2、如果web應用所在目錄更改,只需要更改虛擬目錄對應的實際目錄,而外界仍可以通過原方式訪問新的web應用。Tomcat 中配置虛擬目錄有以下三中方式:...
  • 前面我們已經接觸過幾種數據結構了,有數組、鏈表、Hash表、紅黑樹(二叉查詢樹),今天再來看另外一種數據結構:棧。 什麼是棧呢,我就不找它具體的定義了,直接舉個例子,棧就相當於一個很窄的木桶,我們往木桶里放東西,往外拿東西時會發現,我們最開始放的東西在最底部,最先拿出來的是剛剛放進去的。所以,...
  • Sample.ashx(handler): using System;using System.Collections.Generic;using System.Web;using System.IO;public ...
  • 為什麼要對資料庫進行設計? 當我們要存儲的數據比較少的是後當然不需要對資料庫進行設計,但是當我們對數據的需求量越來越大時對資料庫的設計就很有必要性了!如果資料庫的設計不當會造成數據冗餘、修改複雜、操作數據異常等問題而好的資料庫設計則可以減少不必要的數據冗餘,通過合理的數據規劃提高系統的性能! 什麼是...
  • 在實際的項目開發中我們可能經常要修改已有的代碼,可能我們經常說開閉原則對已有的代碼不准修改,但是實際上很難,那麼下麵的3種方法也許能幫助我們改善對代碼的修改。1:新生方法有時候在我們開發的時候需要像系統加入新的功能時候這個時候我們就可能改變我們原有方法的結構。那麼下麵有一個簡單例子以前添加用戶的.....
  • 1、創建webapi項目,提供介面方法如下:/// /// 獲取租戶、位置下的所有感測器 /// /// [AcceptVerbs("POST")] [Route("api/Sensors/GetSensors")] ...
  • publicstaticvoidDebugFunctionTree(stringmessage){try{System.Diagnostics.StackTracest=newSystem.Diagnostics.StackTrace();System.Diagnostics.StackFrame....
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...