日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

C#的Winform多语言实现(resx文件)

發(fā)布時間:2023/12/18 C# 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C#的Winform多语言实现(resx文件) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?使用resx文件實現(xiàn)Winform多語言切換,本博文提供的代碼可以實現(xiàn)簡體中文、繁體中文、英文的切換。如果需要增加其它語言的切換,只需要編寫相應的語言的resx文件即可。 并且,當修改了語言之后,會更新所有打開的窗口。先貼幾張圖展示一下效果。

程序下載:點擊打開鏈接

http://download.csdn.net/detail/softimite_zifeng/9731575

1. 簡體中文

2. 繁體中文

3. 英文

下面子豐介紹一下實現(xiàn)的過程:

1. 為每個窗口創(chuàng)建相應語言的resx文件。子豐以英文為例,右鍵->添加->新建項->資源文件,文件名為窗口名.en-US,如上面的兩個窗口,分別為LoginForm.en-US.resx和PasswordForm.en-US.resx。簡體中文為LoginForm.zh-CN.resx和PasswordForm.zh-CN.resx,繁體中文為LoginForm.zh-CHT.resx和PasswordForm.zh-CHT.resx。下面給出LoginForm.en-US.resx文件的截圖。

2. 在項目的Properties的Settings.settings中添加變量DefaultLanguage,用于保存當前設置的默認語言。當下次啟動程序時,會讀取該變量,從而將程序的語言設置為上次程序關閉時的語言。

3. 創(chuàng)建一個靜態(tài)類(MultiLanguage.cs)用于編寫與切換語言相關的變量和代碼。

(1)變量DefaultLanguage,用于保存當前默認語言

//當前默認語言
public static string DefaultLanguage = "zh-CN";
(2)函數(shù)SetDefaultLanguage修改當前默認語言
/// <summary>
/// 修改默認語言
/// </summary>
/// <param name="lang">待設置默認語言</param>
public static void SetDefaultLanguage(string lang)
{
? ? System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(lang);
? ? DefaultLanguage = lang;
? ? Properties.Settings.Default.DefaultLanguage = lang;
? ? Properties.Settings.Default.Save();
}
(3)函數(shù)LoadLanguage用于加載語言或切換語言
/// <summary>
/// 加載語言
/// </summary>
/// <param name="form">加載語言的窗口</param>
/// <param name="formType">窗口的類型</param>
public static void LoadLanguage(Form form, Type formType)
{
? ? if (form != null)
? ? {
? ? ? ? System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(formType);
? ? ? ? resources.ApplyResources(form, "$this");
? ? ? ? Loading(form, resources);
? ? }
}
?
/// <summary>
/// 加載語言
/// </summary>
/// <param name="control">控件</param>
/// <param name="resources">語言資源</param>
private static void Loading(Control control, System.ComponentModel.ComponentResourceManager resources)
{
? ? if (control is MenuStrip)
? ? {
? ? ? ? //將資源與控件對應
? ? ? ? resources.ApplyResources(control, control.Name);
? ? ? ? MenuStrip ms = (MenuStrip)control;
? ? ? ? if (ms.Items.Count > 0)
? ? ? ? {
? ? ? ? ? ? foreach (ToolStripMenuItem c in ms.Items)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? //遍歷菜單
? ? ? ? ? ? ? ? Loading(c, resources);
? ? ? ? ? ? }
? ? ? ? }
? ? }
?
? ? foreach (Control c in control.Controls)
? ? {
? ? ? ? resources.ApplyResources(c, c.Name);
? ? ? ? Loading(c, resources);
? ? }
}
?
/// <summary>
/// 遍歷菜單
/// </summary>
/// <param name="item">菜單項</param>
/// <param name="resources">語言資源</param>
private static void Loading(ToolStripMenuItem item, System.ComponentModel.ComponentResourceManager resources)
{
? ? if (item is ToolStripMenuItem)
? ? {
? ? ? ? resources.ApplyResources(item, item.Name);
? ? ? ? ToolStripMenuItem tsmi = (ToolStripMenuItem)item;
? ? ? ? if (tsmi.DropDownItems.Count > 0)
? ? ? ? {
? ? ? ? ? ? foreach (ToolStripMenuItem c in tsmi.DropDownItems)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? Loading(c, resources);
? ? ? ? ? ? }
? ? ? ? }
? ? }
}


4. 在主窗口的Load事件中讀取Properties.Settings.Default.DefaultLanguage,并將ComboBox賦值為當前默認語言,即簡體中文、繁體中文或英文。

private void LoginForm_Load(object sender, EventArgs e)
{
? ? //設置combobox的值
? ? string language = Properties.Settings.Default.DefaultLanguage;
? ? if (language == "zh-CN")
? ? {
? ? ? ? languageTxt.Text = "簡體中文(默認)";
? ? }
? ? else if (language == "zh-CHT")
? ? {
? ? ? ? languageTxt.Text = "繁體中文";
? ? }
? ? else if (language == "en-US")
? ? {
? ? ? ? languageTxt.Text = "English";
? ? }
}

5. 在每個窗口的Load事件中調用函數(shù)MultiLanguage.LoadLanguage,使窗口在出現(xiàn)時即顯示為當前默認語言。

private void PasswordForm_Load(object sender, EventArgs e)
{
? ? //加載語言
? ? MultiLanguage.LoadLanguage(this, typeof(PasswordForm));
}


6. 編寫用于切換語言的ComboBox的SelectedIndexChanged事件,使得當用戶選擇對應的語言時,程序會切換到該語言。
//切換語言
private void languageTxt_SelectedIndexChanged(object sender, EventArgs e)
{
? ? languageTxt.Enabled = false;
? ? if (languageTxt.Text == "簡體中文(默認)")
? ? {
? ? ? ? //修改默認語言
? ? ? ? MultiLanguage.SetDefaultLanguage("zh-CN");
? ? ? ? //對所有打開的窗口重新加載語言
? ? ? ? foreach (Form form in Application.OpenForms)
? ? ? ? {
? ? ? ? ? ? LoadAll(form);
? ? ? ? }
? ? }
? ? else if (languageTxt.Text == "繁體中文")
? ? {
? ? ? ? //修改默認語言
? ? ? ? MultiLanguage.SetDefaultLanguage("zh-CHT");
? ? ? ? //對所有打開的窗口重新加載語言
? ? ? ? foreach (Form form in Application.OpenForms)
? ? ? ? {
? ? ? ? ? ? LoadAll(form);
? ? ? ? }
? ? }
? ? else if (languageTxt.Text == "English")
? ? {
? ? ? ? //修改默認語言
? ? ? ? MultiLanguage.SetDefaultLanguage("en-US");
? ? ? ? //對所有打開的窗口重新加載語言
? ? ? ? foreach (Form form in Application.OpenForms)
? ? ? ? {
? ? ? ? ? ? LoadAll(form);
? ? ? ? }
? ? }
? ? languageTxt.Enabled = true;
}
?
private void LoadAll(Form form)
{
? ? if (form.Name == "LoginForm")
? ? {
? ? ? ? MultiLanguage.LoadLanguage(form, typeof(LoginForm));
? ? }
? ? else if (form.Name == "PasswordForm")
? ? {
? ? ? ? MultiLanguage.LoadLanguage(form, typeof(PasswordForm));
? ? }
}
?

?

//***********

國際化就是要實現(xiàn)多語種的界面切換。首先,我們不可能用if else等語句來根據(jù)選擇的不同語種對所有的控件一個一個的設值,這樣太麻煩了。.Net提供了國際化相關的支持,主要放在System.Globalization命名空間下。下面是一個簡單的實現(xiàn),麻雀雖小,五臟俱全。
這個程序是最近寫的一個程序,就在這基礎上進行改造,關鍵是弄懂原理。
1> 首先要加入Resource文件
在VS工程-->添加新項目里加入三個resource文件,Resource文件的作用就是存放我們的界面控件的顯示字符串。這里我們要實現(xiàn)3種語言的切換,所有加入了3個,分別命名為:Resource.en-US.resx,Resource.zh-CN.resx,Resource.ja-JP.resx。注意命名規(guī)則第一部分要相同,第二部分是不同語言的culture name,我定義的就是英語,中文,日文。
2> 在這3個文件中定義界面相關的字符串信息。
注意定義的名字在3個文件中要一致,否則找不到。
Resource.en-US.resx
tsmi_language_Name?Language
tsmi_japanese_Name?Japanese
tsmi_english_Name?English
tsmi_close_Name?Close
tsmi_chiniese_Name?Chinese

Resource.zh-CN.resx
tsmi_language_Name?語言
tsmi_chiniese_Name?中文
tsmi_english_Name?英文
tsmi_japanese_Name?日文
tsmi_close_Name?退出

Resource.ja-JP.resx
tsmi_language_Name?言語
tsmi_chiniese_Name?中國語
tsmi_english_Name?英語
tsmi_japanese_Name?日本語
tsmi_close_Name?閉じる
3> 利用ResourceManager類進行讀取。
ResourceManager會根據(jù)不同的cultrue來讀不同的resource文件,所以,實現(xiàn)的關鍵就是根據(jù)不同的語言來改變當前程序線程的cultrue就可以達到目地。而對于界面控件Text的賦值代碼將是不變的,當新增加一種語言是,也就是再加一個resource文件,對代碼的改動幾乎沒有影響。
基本代碼:
Resource的讀取類

[csharp]?view plaincopy

  • class?ResourceCluture??
  • {??
  • ????///?<summary>??
  • ????///?設定語言環(huán)境??
  • ????///?</summary>??
  • ????///?<param?name="strClutrue"></param>??
  • ????public?static?void?SetLocalClutrue(string?strClutrue)??
  • ????{??
  • ????????if(string.IsNullOrEmpty(strClutrue))??
  • ????????{??
  • ????????????strClutrue?=?"zh-CN";??
  • ????????}??
  • ????????CultureInfo?currentClutrue?=?new?CultureInfo(strClutrue);??
  • ????????Thread.CurrentThread.CurrentCulture?=?currentClutrue;??
  • ????}??
  • ??
  • ????///?<summary>??
  • ????///?取值??
  • ????///?</summary>??
  • ????///?<param?name="id"></param>??
  • ????///?<returns></returns>??
  • ????public?static?string?GetString(string?id)??
  • ????{??
  • ????????string?strValue?=?string.Empty;??
  • ????????try??
  • ????????{??
  • ????????????ResourceManager?resManager?=?new?ResourceManager("ApplicationActive.Properties.Resource",?Assembly.GetExecutingAssembly());??
  • ????????????strValue?=?resManager.GetString(id,?Thread.CurrentThread.CurrentCulture);??
  • ????????}??
  • ????????catch??
  • ????????{??
  • ????????????strValue?=?"No?id:"?+?id?+?"please?add";??
  • ????????}??
  • ????????return?strValue;??????????
  • ????}??
  • }??
  • //***********************異常

    今天在測試一個工程的時候,突然遇到了這樣一個問題:

    ?

    錯誤信息:System.Resources.MissingManifestResourceException: 未能找到任何適合于指定的區(qū)域或非特定區(qū)域性的資源。請確保在編譯時已將“****.****.Resource.resources”正確嵌入或鏈接到程序集"****",或者確保所有需要的附屬程序集都可加載并已進行了完全簽名。

    在網上搜索了N久都沒看到幾篇解決的文章,最后在不懈的努力下終于解決了,所以決定寫下解決方法方便以后遇到同樣問題的朋友:

    其實這個錯誤的主要問題就是沒有找到需要的資源文件(該文件為Resources.resx),
    引用該文件的地方就是
    System.Resources.ResourceManager manager = new System.Resources.ResourceManager("×××.Resources", typeof(Resources).Assembly);
    而導致錯誤的原因就是"×××.Resources"的配置錯誤

    解決方法:首先查看工程中時候存在Resources.resx相關的文件,
    找到它在工程中的位置(不如說一般都是在:工程名.Properties 命名空間下),
    最后更改配置為new System.Resources.ResourceManager("工程名.Properties.Resources", typeof(Resources).Assembly);

    續(xù):

    我這里在舉個詳細的例子,以便能夠更明白哈

    首先,一個容器(不管是Form,或是Panel也好),如果與其配套一個資源文件(以后綴名為.resx),則這2個文件應是在同一個命名空間下,才能相互使用

    舉個最特殊的例子

    比如說一個工程名叫Test.Tname

    其下有一個文件夾叫aaa(文件夾名字隨便,沒有關系)

    文件夾aaa下有一個類文件叫Form1.cs,其命名空間為:Test.Tname(注意:命名空間才是重要的位置信息)

    現(xiàn)在也有一個資源文件叫Form1.resx

    (默認此資源文件是沒有問題的,但是在特別的情況下,此文件就不會再正確的位置,導致出現(xiàn)如題的異常信息,比如說我反編譯一個工程,自動生成的資源文件的位置就有問題)。

    在Form1.cs中有句代碼是需要資源文件的

    ResourceManager manager = new ResourceManager(typeof(Test.Tname.Form1));

    這里就注意了,如果Form1.cs類文件與Form1.resx資源文件是分開的話,

    那么Form1.resx資源文件應放在哪個地方,程序才能找到他呢?

    首先我們看哈Form1.cs類文件的命名空間為Test.Tname。

    而資源文件Form1.resx中并沒有命名空間的描述,所以只有靠位置來表示

    再看下我們的工程名稱:Test.Tname很好,它跟Form1.cs類文件的命名空間相同

    所以我們就把Form1.resx資源文件放在工程的根目錄下面

    問題解決了,呵呵

    其實我覺得最重要的問題就是類文件中可以有namespace來描述位置

    而資源文件中并沒有這行代碼,只能靠真正的位置,這才是關鍵

    總結

    以上是生活随笔為你收集整理的C#的Winform多语言实现(resx文件)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。