一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - C# - 在WinForm應用程序中快速實現多語言的處理的方法

在WinForm應用程序中快速實現多語言的處理的方法

2022-02-25 14:37伍華聰 C#

在國際化環境下,越來越多的程序需要做多語言版本,這篇文章主要介紹了在WinForm應用程序中快速實現多語言的處理的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下。

在國際化環境下,越來越多的程序需要做多語言版本,以適應各種業務需求的變化。在winform應用程序中實現多語言也有常規的處理方式處理,不過需要針對每個語言版本,重新修改winform界面的顯示,對一些常規的輔助類,也需要引入一個統一的資源管理類來處理多語言的問題,相對比較繁瑣。本篇隨筆針對多語言的需求,希望盡量避免繁瑣的操作,既能符合本地語種開發人員的開發習慣,又能快速實現winform程序的多語言場景處理。

1、多語言開發的困惑和思路

在常規的多語言版本程序中,開發總是伴隨著很多不愉快的事情,大概列舉一些僅供參考:

1)對窗體的多語言處理時,維護多個語言版本的界面非常繁瑣;

2)多語言處理的時候,以資源參照的時候,默認鍵值為一些英文字符串或者單詞,不太符合如中文語境的開發,調整代碼則需要很多工作量;

3)對于已開發好的程序,全面引入多語言的處理代碼,需要大量修改;

4)對于大量中文的多語言處理,工作量望而卻步;

5)對于常規resx文件的處理覺得繁瑣

6)缺乏一個統一處理多語言需求的方案

在多語言的處理上,我一直希望找出一種高效的處理方式,由于我的winform開發框架中很多模塊是現成的,希望能夠使用繼承處理的方式,實現最簡化的處理;

同時大量中文的英文(針對英文版本)翻譯也是一個頭痛的事情,突然想到百度的翻譯api接口可以利用,那么我們可以利用翻譯接口實現開始的翻譯,然后對資源進行一定的調整則可以提高效率和準確率。

對于編輯和承載多語言的信息,我一直覺得json格式挺好的,可以利用它序列化為字典集合,通過字典獲取對應鍵值的多語言版本字符串也是很高效的一種方式,那么就決定用json來存儲多語言信息了,易讀好用。

對于多余的處理邏輯,盡量封裝為獨立的模塊,可以在多個模塊中進行調用處理。

2、多語言的處理實現

在思考多語言的合理處理方案過程中,參考了另一位博友的文章《分享兩種實現winform程序的多語言支持的解決方案》,思路有點符合我的期望,因此吸收了一些處理思想進行處理,目的就是提高開發效率。

1)多語言的信息存儲和加載

首先,我們來看看多語言處理的目錄和格式問題,目錄大概是根據多語言的簡稱進行放置,如下所示。

在WinForm應用程序中快速實現多語言的處理的方法

這個目錄就是會輸出到debug或者release的運行目錄中,我們就是根據相對于運行目錄進行資源讀取即可,所有模塊共用同一的多語言文件,我們可以把各個模塊基礎通用的多語言文件放在basic.json文件中,也可以根據模塊獨立起名,主程序如testmultilanguage的多語言文件我則放在testmultilanguage.json文件中。實際上目錄名稱是為了區分而已,程序加載的時候,會把目錄下面所有的json文件進行加載,讀取里面的鍵值作為資源的字典參照。

多語言的json文件是標準的json格式,只是我們只用鍵值的字典參考即可,不需要使用復雜的json對象格式,如下是basic.json文件的部分內容。

在WinForm應用程序中快速實現多語言的處理的方法

這些資源文件采用中文-英文的參照方式,我們以我們常規的母語開發,即使我們不做多語言,也不影響代碼的正常處理,我們只需要把窗體上和代碼里面的中文提取出來,然后進行多語言處理(如變為英文)即可。

由于我們使用鍵值字典對象的json內容,那么我們就可以把這些內容序列號為字典集合,如下代碼我們可以通過 json.net 組件把它們序列化為字典集合,這些字典集合就是我們用來做多語言的關鍵。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var content = file.readalltext(file, encoding.utf8);
      if (!string.isnullorempty(content))
      {
        var dict = jsonconvert.deserializeobject<dictionary<string, string>>(content);
        foreach (string key in dict.keys)
        {
          //遍歷集合如果語言資源鍵值不存在,則創建,否則更新
          if (!resources.containskey(key))
          {
            resources.add(key, dict[key]);
          }
          else
          {
            resources[key] = dict[key];
          }
        }
      }

加載多語言處理的時候,我們遍歷相對目錄下的lang/***里面的文件即可實現多語言信息的加載,如下代碼所示。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/// <summary>
    /// 根據語言初始化信息。
    /// 加載對應語言的json信息,把翻譯信息存儲在全屬性resources里面。
    /// </summary>
    /// <param name="language">默認的語言類型,如zh-hans,en-us等</param>
    private void loadlanguage(string language = "")
    {
      if (string.isnullorempty(language))
      {
        language = system.threading.thread.currentthread.currentuiculture.name;
      }
 
      this.resources = new dictionary<string, string>();
      string dir = path.combine(appdomain.currentdomain.basedirectory, string.format("lang/{0}", language));
      if (directory.exists(dir))
      {
        var jsonfiles = directory.getfiles(dir, "*.json", searchoption.alldirectories);
        foreach (string file in jsonfiles)
        {
          loadfile(file);
        }
      }
    }

我們把多語言的加載和翻譯處理,放在一個獨立的項目上,如我定義為框架的一個模塊:whc.framework.language

這樣我們在各個模塊中使用多語言處理過程的時候,包含這個模塊就可以了。

2)多語言信息的翻譯

做多語言的版本程序,翻譯工作也是一個繁瑣的工作,如果你是非常精通各種語言(如中文、英文、日文等等),那當然不在話下,不過我們做開發的多少也是會一些的,如英語吧,即時不能非常準確,那么也可以做到差不多,但是做這個還是累,還容易敲打錯別字,那么用第三方提供的翻譯api來預處理后調整,結果就簡化很多了,可以極大提高效率的。

這里以我們經常使用的百度翻譯來實現(用google翻譯也可以,增加接口實現即可)

百度翻譯接口的使用,你先注冊一個開發賬戶,獲得相應的秘鑰信息就可以使用免費的翻譯接口了()。

在WinForm應用程序中快速實現多語言的處理的方法

有了這些準備后,就可以利用c#代碼進行翻譯處理了。

百度翻譯的接口處理代碼如下所示。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/// <summary>
    /// 百度接口翻譯
    /// </summary>
    /// <param name="inputstring">輸入字符串</param>
    /// <param name="from">源內容語言</param>
    /// <param name="to">目標語言</param>
    /// <returns></returns>
    private static string baidutranslate(string inputstring, string from = "zh", string to = "en")
    {
      string content = "";
 
      string appid = "你的appid";
      string securityid = "你的秘鑰";
      int salt = 0;
 
      stringbuilder signstring = new stringbuilder();
      string md5result = string.empty;
      //1.拼接字符,為了生成sign
      signstring.append(appid);
      signstring.append(inputstring);
      signstring.append(salt);
      signstring.append(securityid);
 
      //2.通過md5獲取sign
      byte[] sourcemd5byte = encoding.utf8.getbytes(signstring.tostring());
      md5 md5 = new md5cryptoserviceprovider();
      byte[] destmd5byte = md5.computehash(sourcemd5byte);
      md5result = bitconverter.tostring(destmd5byte).replace("-", "");
      md5result = md5result.tolower();
 
      try
      {
        //3.獲取web翻譯的json結果
        webclient client = new webclient();
        string url = string.format("http://api.fanyi.baidu.com/api/trans/vip/translate?q={0}&from=zh&to=en&appid={1}&salt={2}&sign={3}", inputstring, appid, salt, md5result);
        byte[] buffer = client.downloaddata(url);
        string result = encoding.utf8.getstring(buffer);
 
        var trans = jsonconvert.deserializeobject<translationjson>(result);
        if (trans != null)
        {
          content = trans.trans_result[0].dst;
          content = stringutil.topropercase(content);
        }
      }
      catch(exception ex)
      {
        debug.writeline(ex);
      }
      return content;
    }

其中把json轉換為類對象需要兩個類,對翻譯結果進行轉換,如下代碼所示。

?
1
2
3
4
5
6
7
8
9
10
11
internal class translationjson
  {
    public string from { get; set; }
    public string to { get; set; }
    public list<translationresult> trans_result { get; set; }
  }
  internal class translationresult
  {
    public string src { get; set; }
    public string dst { get; set; }
  }

這樣我們在多語言處理的時候,可以對默認輸入為空的鍵值進行翻譯即可(如英文翻譯)。

?
1
2
3
4
5
6
7
8
9
10
11
//遍歷集合進行翻譯
  var value = dict[key];
  if (string.isnullorwhitespace(value))
  {
    //如果值為空,那么調用翻譯接口處理
    var newvalue = translationhelper.translate(key, from, to);
    if (!string.isnullorwhitespace(newvalue))
    {
      dict[key] = newvalue;
    }
  }

然后重新更新我們的資源文件就可以了

?
1
2
3
4
//不排序
 var newcontent = jsonconvert.serializeobject(dict, formatting.indented);
 
 file.writealltext(file, newcontent, encoding.utf8);

如果需要對鍵值進行排序,那么使用sortdictionary進行包裝下即可

?
1
2
3
//進行排序
  sorteddictionary<string, string> sorteddict = new sorteddictionary<string, string>(dict);
  var newcontent = jsonconvert.serializeobject(sorteddict, formatting.indented);

在多語言處理的時候,我們一般不必要一次填寫完畢中英文對照的資源,我們可以先把字典鍵值的鍵寫出來,值保留為空,如下文件所示。

在WinForm應用程序中快速實現多語言的處理的方法

運行程序的時候,讓翻譯的接口先行翻譯,然后我們再對翻譯的資源進行調整,適應我們程序的語境即可,翻譯后的內容后如下所示。

在WinForm應用程序中快速實現多語言的處理的方法

好了,彈藥都準備好了,就看我們如何使用, 下一步介紹如何使用這些資源。

3、多語言在界面中的應用

前面介紹都是為程序界面準備好對應的多語言資源內容,我們在程序啟動的時候,可以通過常規的方式,設置界面的currentuiculture區域信息,如下代碼所示。

?
1
2
3
//界面多語言
      //system.threading.thread.currentthread.currentuiculture = new system.globalization.cultureinfo("zh-hans");//中文界面
      system.threading.thread.currentthread.currentuiculture = new system.globalization.cultureinfo("en-us");//英文界面

然后我們在winform程序中開發設計我們的界面內容,例如設計一個普通的界面如下所示。

在WinForm應用程序中快速實現多語言的處理的方法

這個窗體我們添加了幾個按鈕,并設置它的中文顯示內容,它的基類默認還是保持它的devexpress基類xtraform,如下所示。

?
1
2
3
4
/// <summary>
  /// 測試多語言的窗體界面
  /// </summary>
  public partial class form1 : xtraform

那么我們如果要自動實現多語言的處理,那么還需要在窗體的load或者shown事件里面實現處理,如下代碼所示。

?
1
2
3
4
5
6
7
8
private void form1_shown(object sender, eventargs e)
    {
      //窗體加載并顯示后,對窗體實現多語言處理
      if (!this.designmode)
      {
        languagehelper.initlanguage(this);
      }
    }

如果我們為每個窗體都需要添加這些代碼,也是繁瑣的事情,那么我們可以把這個處理邏輯,放到我們常規自定義的窗體基類里面(如baseform),那么我們就不需要任何額外的代碼了。

所需的就是集成窗體基類即可,這也是我們一般開發都做的事情,通過繼承使得我們的代碼又省去了。

?
1
2
3
4
/// <summary>
  /// 測試多語言的窗體界面
  /// </summary>
  public partial class form1 : baseform

那么我們真正關注的就是我們前面介紹的邏輯代碼實現了

?
1
languagehelper.initlanguage(this);

這個輔助類,主要就是在窗體初始化后,遍歷界面的所有類型控件,對控件進行相應的多語言處理。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/// <summary>
  /// 對界面控件進行多語言的處理輔助類
  /// </summary>
  public class languagehelper
  {      
    /// <summary>
    /// 初始化語言
    /// </summary>
    public static void initlanguage(control control)
    {
      //如果沒有資源,那么不必遍歷控件,提高速度
      if (!jsonlanguage.default.hasresource)
        return;
 
      //使用遞歸的方式對控件及其子控件進行處理
      setcontrollanguage(control);
      foreach (control ctrl in control.controls)
      {
        initlanguage(ctrl);
      }
 
      //工具欄或者菜單動態構建窗體或者控件的時候,重新對子控件進行處理
      control.controladded += (sender, e) =>
      {
        initlanguage(e.control);
      };
    }

通過遞歸的方式,我們可以對常規的如gridcontrol,工具欄、navbar導航欄、菜單、按鈕等資源進行統一的多語言處理,而這里面對于我們開發應用程序界面,都不需要額外的擔心,極大的提高了效率。

下面是幾個常規的界面,我們來體驗下英文版本的界面效果。

在WinForm應用程序中快速實現多語言的處理的方法

在WinForm應用程序中快速實現多語言的處理的方法

在WinForm應用程序中快速實現多語言的處理的方法

在WinForm應用程序中快速實現多語言的處理的方法

在WinForm應用程序中快速實現多語言的處理的方法

這些英文界面我們只需要把界面的中文提取出來放到json文件中,自動翻譯再調整即可,然后界面繼承保持baseform或者basedock這些窗體基類不變,只是調整了這些基類的加載,增加一行代碼就可以順利實現了多語言的效果了。

這樣我們就把核心的工作放在提取界面中的中文資源并進行整理即可,這是核心的工作但翻譯也基本不用自己從頭做,窗體代碼幾乎不需要做其他修改就實現了我們所需要的多語言效果了,這樣做極大提高了開發效率,對于我們已經開發好的模塊,更是四兩撥千斤了。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:http://www.cnblogs.com/wuhuacong/p/9007270.html

延伸 · 閱讀

精彩推薦
  • C#C#通過KD樹進行距離最近點的查找

    C#通過KD樹進行距離最近點的查找

    這篇文章主要為大家詳細介紹了C#通過KD樹進行距離最近點的查找,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    帆帆帆6112022-01-22
  • C#Unity3D實現虛擬按鈕控制人物移動效果

    Unity3D實現虛擬按鈕控制人物移動效果

    這篇文章主要為大家詳細介紹了Unity3D實現虛擬按鈕控制人物移動效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一...

    shenqingyu060520232410972022-03-11
  • C#WPF 自定義雷達圖開發實例教程

    WPF 自定義雷達圖開發實例教程

    這篇文章主要介紹了WPF 自定義雷達圖開發實例教程,本文介紹的非常詳細,具有參考借鑒價值,需要的朋友可以參考下...

    WinterFish13112021-12-06
  • C#C#實現XML文件讀取

    C#實現XML文件讀取

    這篇文章主要為大家詳細介紹了C#實現XML文件讀取的相關代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    Just_for_Myself6702022-02-22
  • C#C#裁剪,縮放,清晰度,水印處理操作示例

    C#裁剪,縮放,清晰度,水印處理操作示例

    這篇文章主要為大家詳細介紹了C#裁剪,縮放,清晰度,水印處理操作示例,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    吳 劍8332021-12-08
  • C#C# 實現對PPT文檔加密、解密及重置密碼的操作方法

    C# 實現對PPT文檔加密、解密及重置密碼的操作方法

    這篇文章主要介紹了C# 實現對PPT文檔加密、解密及重置密碼的操作方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下...

    E-iceblue5012022-02-12
  • C#C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題實例

    C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題實例

    這篇文章主要介紹了C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題,簡單描述了訪問者模式的定義并結合具體實例形式分析了C#使用訪問者模式解決長...

    GhostRider9502022-01-21
  • C#深入解析C#中的交錯數組與隱式類型的數組

    深入解析C#中的交錯數組與隱式類型的數組

    這篇文章主要介紹了深入解析C#中的交錯數組與隱式類型的數組,隱式類型的數組通常與匿名類型以及對象初始值設定項和集合初始值設定項一起使用,需要的...

    C#教程網6172021-11-09
主站蜘蛛池模板: 日韩无遮挡大尺度啪啪影片 | 我的漂亮朋友在线观看全集免费 | 欧美性一级交视频 | 按摩师他揉我奶好爽捏我奶 | 加勒比一本大道在线 | 久久人妻少妇嫩草AV无码 | 免费毛片在线观看 | 亚洲AV无码一区二区三区乱子伦 | 明星乱亚洲 | 亚洲天堂.com | 国产成人精品日本亚洲网站 | 美日毛片| bdsm中国精品调教 | 幻女free性俄罗斯第一次摘花 | 无限在线观看视频大全免费高清 | 大伊香蕉精品二区视频在线 | 亚洲视屏在线观看 | china外卖员gay国产xnxx | 双子母性本能在线观看 | 欧美区视频 | 女教师波多野结衣高清在线 | 俄罗斯三级在线观看级 | 四虎影视在线看免费 720p | 国产成人一级 | 国产亚洲精品aaa大片 | 国产小视频在线免费观看 | 国产情侣自拍网 | 亚洲成人伦理 | 91精品国产品国语在线不卡 | 日韩国产欧美视频 | 99福利在线观看 | 久99视频精品免费观看福利 | tk白嫩玉足脚心vk | 日本黄色大片网站 | xxx老妇人60 xxxx意大利xxxxhd | 欧美成人在线影院 | 欧美综合精品一区二区三区 | 国产高清久久 | 女人张开腿 让男人桶个爽 免费观看 | 国产日韩欧美不卡www | 日韩精品视频美在线精品视频 |