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

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - C# - 分享兩種實(shí)現(xiàn)Winform程序的多語(yǔ)言支持的多種解決方案

分享兩種實(shí)現(xiàn)Winform程序的多語(yǔ)言支持的多種解決方案

2021-12-22 13:58夢(mèng)在旅途 C#

本篇文章主要介紹了分享兩種實(shí)現(xiàn)Winform程序的多語(yǔ)言支持的多種解決方案,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧。

因公司業(yè)務(wù)需要,需要將原有的ERP系統(tǒng)加上支持繁體語(yǔ)言,但不能改變?cè)械木幋a方式,即:普通程序員感受不到編碼有什么不同。經(jīng)過(guò)我與幾個(gè)同事的多番溝通,確定了以下兩種方案:

方案一:在窗體基類中每次加載并顯示窗體時(shí),會(huì)自動(dòng)遞歸遍歷含文本顯示的控件(Button,CheckBox,GroupBox,Label,LinkLabel,TextBox,StatusStrip,TabPage,ToolStrip,RadioButton,DateTimePicker,DataGridView,CheckedListBox,TreeView,MenuStrip),并根據(jù)不同的控件類型的文本屬性調(diào)用簡(jiǎn)繁轉(zhuǎn)換方法進(jìn)行轉(zhuǎn)換并重新設(shè)置新的相應(yīng)文本屬性的內(nèi)容(比如:繁體內(nèi)容)

優(yōu)點(diǎn):編碼簡(jiǎn)單,對(duì)普通程序員的編碼無(wú)影響(除窗體類的基類由Form類變成MyStyleFormBase類);

缺點(diǎn):因每次打開(kāi)窗體都需要遍歷控件并進(jìn)行簡(jiǎn)繁轉(zhuǎn)換,如果界面上的控件較多,則可能導(dǎo)致打開(kāi)窗體較慢,影響用戶體驗(yàn),且子控件的文本內(nèi)容改變時(shí)需程序員手動(dòng)通知,無(wú)法自動(dòng)感知并轉(zhuǎn)換。

具體實(shí)現(xiàn)思路如下:

一.對(duì)Form類進(jìn)行二次封裝(繼承),定義一個(gè)MyStyleFormBase類,并在里面加入每次加載并顯示窗體類型時(shí),會(huì)自動(dòng)遞歸遍歷含文本顯示的控件,并根據(jù)不同的控件類型的文本屬性調(diào)用簡(jiǎn)繁轉(zhuǎn)換方法進(jìn)行轉(zhuǎn)換并重新設(shè)置新的相應(yīng)文本屬性的內(nèi)容,這樣當(dāng)所有的窗體都繼承MyStyleFormBase類時(shí),均默認(rèn)就實(shí)現(xiàn)了遍歷與轉(zhuǎn)換的過(guò)程,程序員無(wú)需再次編碼,甚至都無(wú)需知道存在遍歷與轉(zhuǎn)換的過(guò)程,從而提高了代碼的復(fù)用性,具體代碼如下:

?
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
public class MyStyleFormBase : Form
 
{
 
 public MyStyleFormBase()
 
 {
 
 if (!Thread.CurrentThread.CurrentUICulture.Name.Equals("zh-CHS", StringComparison.OrdinalIgnoreCase)) //如果是簡(jiǎn)體,則無(wú)需轉(zhuǎn)換
 
 {
 
 base.TextChanged += MyStyleFormBase_TextChanged;
 
 base.Shown += MyStyleFormBase_Shown;
 
 }
 
 }
 
 
 
 private void MyStyleFormBase_TextChanged(object sender, EventArgs e)
 
 {
 
 this.Text = LanguageHelper.GetLanguageText(this.Text);
 
 }
 
 
 
 private void MyStyleFormBase_Shown(object sender, EventArgs e)
 
 {
 
 LanguageHelper.SetControlLanguageText(this);
 
 base.ControlAdded += MyStyleFormBase_ControlAdded;
 
 }
 
 
 
 private void MyStyleFormBase_ControlAdded(object sender, ControlEventArgs e)
 
 {
 
 LanguageHelper.SetControlLanguageText(e.Control);
 
 }
 
 
 
 /// <summary>
 
 /// 強(qiáng)制通知子控件改變消息
 
 /// </summary>
 
 /// <param name="target"></param>
 
 protected virtual void PerformChildrenChange(Control target)
 
 {
 
 LanguageHelper.SetControlLanguageText(target);
 
 }
 
 
 
 /// <summary>
 
 /// 彈出消息框
 
 /// </summary>
 
 /// <param name="text"></param>
 
 /// <param name="caption"></param>
 
 /// <param name="buttons"></param>
 
 /// <param name="icon"></param>
 
 /// <param name="defaultButton"></param>
 
 /// <returns></returns>
 
 protected DialogResult MessageBoxShow(string text, string caption, MessageBoxButtons buttons = MessageBoxButtons.OK, MessageBoxIcon icon = MessageBoxIcon.None, MessageBoxDefaultButton defaultButton = MessageBoxDefaultButton.Button1)
 
 {
 
 return MessageBox.Show(LanguageHelper.GetLanguageText(text), LanguageHelper.GetLanguageText(caption), buttons, icon, defaultButton);
 
 }
 
}

代碼邏輯簡(jiǎn)要說(shuō)明:

1.當(dāng)當(dāng)前UI的文化區(qū)域不為中文簡(jiǎn)體時(shí)(因?yàn)楸境绦虮旧矶际腔诤?jiǎn)體開(kāi)發(fā)的),就訂閱窗體顯示事件Shown及窗體標(biāo)題改變事件TextChanged,作用:當(dāng)窗體顯示時(shí),則會(huì)遍歷控件并轉(zhuǎn)換為繁體,當(dāng)標(biāo)題的文本改變時(shí),也會(huì)自動(dòng)轉(zhuǎn)換為繁體;

2.當(dāng)窗體顯示后訂閱窗體的控件增加事件ControlAdded,作用:當(dāng)窗體顯示后,若后續(xù)存在代碼增加控件時(shí),會(huì)自動(dòng)將控件及其子控件進(jìn)行繁體的轉(zhuǎn)換,保證一個(gè)都不漏;

3.增加一個(gè)消息提示框方法,目的是彈出消息窗口前能夠?qū)⒑?jiǎn)體文本轉(zhuǎn)換成繁體文本;

4.增加一個(gè)強(qiáng)制通知子控件改變消息的方法PerformChildrenChange,當(dāng)某個(gè)控件的文本內(nèi)容或增加子控件發(fā)生時(shí),由于窗體本身無(wú)法捕獲到,故需要調(diào)用該方法來(lái)遍歷與轉(zhuǎn)換子控件的文本內(nèi)容;(感覺(jué)這里不太好,但目前沒(méi)有更好的辦法,如果大家有更好的辦法,歡迎留言評(píng)論)

 二、LanguageHelper:語(yǔ)方轉(zhuǎn)換公共類(目前僅支持簡(jiǎn)繁轉(zhuǎn)換,依賴于:ChineseConverter.dll)代碼如下:

由于代碼過(guò)長(zhǎng),請(qǐng)點(diǎn)擊下載

該類邏輯很簡(jiǎn)單,就是從一個(gè)父控件開(kāi)始,遍歷所有的子控件,并根據(jù)不同的控件類型將控件相應(yīng)的文本內(nèi)容轉(zhuǎn)換成簡(jiǎn)體或繁體,調(diào)用方法:SetControlLanguageText

以上二步就實(shí)現(xiàn)了多語(yǔ)言的支持了(準(zhǔn)確的說(shuō)是簡(jiǎn)繁轉(zhuǎn)換),應(yīng)用到項(xiàng)目中很簡(jiǎn)單,只需將窗體默認(rèn)的基類Form改成:MyStyleFormBase即可,如:public partial class FormTest : MyStyleFormBase

方案二:由控件依據(jù)當(dāng)前區(qū)域信息+緩存語(yǔ)言字典直接實(shí)現(xiàn)各控件自行轉(zhuǎn)換

優(yōu)點(diǎn):無(wú)需遍歷,各控件自行根據(jù)區(qū)域信息自支轉(zhuǎn)換,因此效率較高,對(duì)普通程序員的編碼無(wú)影響(除窗體類的基類由Form類變成MyStyleFormBase類外,還需要使用支持多語(yǔ)言的控件,這些控件均由普通控件二次封裝得來(lái),保留原有的所有屬性及事件);

缺點(diǎn):需將所有帶文本顯示的控件(如:Button,CheckBox,GroupBox,Label,LinkLabel,TextBox,StatusStrip,TabPage,ToolStrip,RadioButton,DateTimePicker,DataGridView,CheckedListBox,TreeView)均進(jìn)行二次封裝,控件統(tǒng)一命名為:MyStyleXXX

 涉及的控件較多,編碼相對(duì)復(fù)雜;

具體實(shí)現(xiàn)思路如下:

一.對(duì)Form類進(jìn)行二次封裝(繼承),定義一個(gè)MyStyleFormBase類,里面加入對(duì)窗體標(biāo)題進(jìn)行修改時(shí),能自動(dòng)進(jìn)行多語(yǔ)言轉(zhuǎn)換功能,具體代碼如下:

?
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
public partial class MyStyleFormBase : Form
 
{
 public MyStyleFormBase()
 {
 base.TextChanged += MyStyleFormBase_TextChanged;
 }
 private void MyStyleFormBase_TextChanged(object sender, EventArgs e)
 
 {
 if (!Common.IsChsLanguage())
 { this.Text = LanguageHelper.GetLanguageText(this.Text); }
 }
 /// <summary>
 /// 彈出消息框
 /// </summary>
 /// <param name="text"></param>
 /// <param name="caption"></param>
 /// <param name="buttons"></param>
 /// <param name="icon"></param>
 /// <param name="defaultButton"></param>
 /// <returns></returns>
 protected DialogResult MessageBoxShow(string text, string caption = "提示", MessageBoxButtons buttons = MessageBoxButtons.OK, MessageBoxIcon icon = MessageBoxIcon.None, MessageBoxDefaultButton defaultButton = MessageBoxDefaultButton.Button1)
 
 {
 if (!Common.IsChsLanguage())
 
 {
 
 text = LanguageHelper.GetLanguageText(text);
 caption = LanguageHelper.GetLanguageText(caption);
 }
 return MessageBox.Show(text, caption, buttons, icon, defaultButton);
 }
}

代碼邏輯很簡(jiǎn)單,就是訂閱一個(gè)Form.TextChanged事件,以便當(dāng)根據(jù)IsChsLanguage(判斷是否為簡(jiǎn)體模式)判斷不是簡(jiǎn)體時(shí),則需進(jìn)行Form.Text轉(zhuǎn)換

二.定義多語(yǔ)言支持普通控件及容器控件接口(IMultiLanguageControl、IMultiLanguageContainerControl),具體代碼如下:(此處僅是為了作一個(gè)規(guī)范,支持手動(dòng)設(shè)置轉(zhuǎn)換控件的文本內(nèi)容)

?
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
/// <summary>
/// 支持多語(yǔ)言普通控件(無(wú)子控件)
/// </summary>
public interface IMultiLanguageControl
{
 string DefaultLangText { get; }
 string CurrentLangText { get; set; }
}
/// <summary>
/// 支持多語(yǔ)言容器控件(包含子控件)
/// </summary>
public interface IMultiLanguageContainerControl
{
 Dictionary<object, string> DefaultLangTexts { get; }
 Dictionary<object, string> CurrentLangTexts { get; set; }
 Control this[string ctrlName] { get; set; }
 void SetItemCurrentLangText(string ctrlName, string langText);
event EventHandler<ChildrenAddedEventArgs> ChildrenChanged;
}
public class ChildrenAddedEventArgs : EventArgs
 
{
 public Dictionary<object, string> LangTexts { get; private set; }
 public ChildrenAddedEventArgs()
 {
 LangTexts = new Dictionary<object, string>();
 
 }
 public ChildrenAddedEventArgs(Dictionary<object, string> langTexts)
 
 { this.LangTexts = langTexts; }
 
 public string this[object key]
 {get
 {
return LangTexts[key];
 }
set
 {
 LangTexts[key] = value;
 } }}

三、實(shí)現(xiàn)支持多語(yǔ)言普通控件:基于原有標(biāo)準(zhǔn)控件(Button,CheckBox,GroupBox,Label,LinkLabel,TextBox,RadioButton,DateTimePicker)進(jìn)行二次封裝,實(shí)現(xiàn)IMultiLanguageControl接口,各控件代碼如下:

以下是MyStyleButton定義代碼,MyStyleCheckBox、MyStyleGroupBox、MyStyleLabel、MyStyleLinkLabel、MyStyleTextBox、MyStyleRadioButton里面的實(shí)現(xiàn)代碼均相同

?
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
public partial class MyStyleButton : MyButton, IMultiLanguageControl
 
 {
 static Dictionary<string, string> LanDict = new Dictionary<string, string>();
 public MyStyleButton()
 { }
 
 public override string Text
 
 {
 
 get
 
 {
 
 if (!DesignMode && System.Threading.Thread.CurrentThread.CurrentUICulture.Name != "zh-CHS")
 {
 if (LanDict.ContainsKey(DefaultLangText))
 
 {
 return CurrentLangText;
 
 }
else
 {
 string langText = LanguageHelper.GetLanguageText(base.Text);
 LanDict[base.Text] = langText;
return langText;
 }
 
 }
 return base.Text;
 
 }
set
 {
 base.Text = value;
 }
 }
 [Browsable(false)]
 
 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
 
 public string DefaultLangText
 
 {
 
 get
 
 {
 
 return base.Text;
 
 }
 }
 
 [Browsable(false)]
 
 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
 
 public string CurrentLangText
 
 {
 get
 {
try
 {
 
 return LanDict[DefaultLangText];
 
 }
 catch (Exception)
 {
 
 return "";
 }
 }
 
set
 {
 
 if (System.Threading.Thread.CurrentThread.CurrentUICulture.Name != "zh-CHS")
 
 {
 
 if (LanDict.ContainsKey(DefaultLangText))
 
 {
 
 LanDict[DefaultLangText] = value;
 
 }
 
 else
 
 {
 
 LanDict.Add(DefaultLangText, value);
 
 }
 
 }
 
 }
 
 }
 
 }

二次封裝這些控件的目的是:1.暴露統(tǒng)一的屬性,便于直接遍歷并賦值(需手動(dòng)改變文本內(nèi)容語(yǔ)言的情況);2.當(dāng)文本內(nèi)容發(fā)生改變時(shí),能夠根據(jù)語(yǔ)言緩存字典,快速直接的自我簡(jiǎn)繁轉(zhuǎn)換,無(wú)需再次遍歷;

四、實(shí)現(xiàn)支持多語(yǔ)言容器控件:基于原有標(biāo)準(zhǔn)控件(StatusStrip,TabPage,ToolStrip,DataGridView,CheckedListBox,TreeView)進(jìn)行二次封裝,實(shí)現(xiàn)IMultiLanguageContainerControl接口,各控件代碼如下:

MyStyleDataGridView:

由于代碼過(guò)長(zhǎng),請(qǐng)點(diǎn)擊下載

MyStyleTabControl:

由于代碼過(guò)長(zhǎng),請(qǐng)點(diǎn)擊下載

二次封裝這些控件的目的是:1.暴露統(tǒng)一的屬性,便于直接遍歷并賦值(僅當(dāng)直接改變文本內(nèi)容語(yǔ)言時(shí)需要);2.當(dāng)文本內(nèi)容或子控件文本內(nèi)容或新增子控件發(fā)生改變時(shí),能夠根據(jù)語(yǔ)言緩存字典,快速直接的自我簡(jiǎn)繁轉(zhuǎn)換,無(wú)需再次遍歷;

五.LanguageHelper:語(yǔ)方轉(zhuǎn)換公共類,與方案一原理相同,但相對(duì)方案一要簡(jiǎn)單很多,代碼如下:

由于代碼過(guò)長(zhǎng),請(qǐng)點(diǎn)擊下載

Common.IsChsLanguage方法定義如下:

?
1
2
3
4
5
6
7
public static bool IsChsLanguage()
 
{
 
 return System.Threading.Thread.CurrentThread.CurrentUICulture.Name.Equals("zh-CHS", StringComparison.OrdinalIgnoreCase);
 
}

多語(yǔ)言支持的容器類控件的實(shí)現(xiàn)難點(diǎn)是:捕獲子控件文本內(nèi)容的改變,由于沒(méi)有現(xiàn)成的事件或方法,故需要通過(guò)其它的途徑來(lái)實(shí)現(xiàn)文本內(nèi)容改時(shí)能夠進(jìn)行處理。

以上就是本文的全部?jī)?nèi)容,有人可能會(huì)說(shuō),為何不采用資源文件的形式,原因文章一開(kāi)頭就說(shuō)明了,是在原有的系統(tǒng)上,且不能改變?cè)械木幋a風(fēng)格,故才花了這么大的力氣來(lái)實(shí)現(xiàn)這個(gè)簡(jiǎn)繁轉(zhuǎn)換的功能,我公司經(jīng)領(lǐng)導(dǎo)確認(rèn)最終采用的方案二。文中若有不足,歡迎交流,謝謝!

注:控件的實(shí)現(xiàn)代碼都貼出來(lái)了,大家若需要的話,可以直接COPY走,另外為了系統(tǒng)安全,簡(jiǎn)繁體的系統(tǒng)截圖我就不貼出來(lái)了,大家可以自行測(cè)試。

原文鏈接:http://www.cnblogs.com/zuowj/p/5878228.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久久国产伦子伦精品 | 我和黑色丝袜班主任 | 美女撒尿部位无遮挡 | 欧美大片一级片 | 成人久久伊人精品伊人 | 日本在线色 | 9 1 视频在线 | 国产精品永久免费10000 | 日韩色在线观看 | 日本强不卡在线观看 | 亚1洲二区三区四区免费 | 久久国产香蕉 | 精品国产一区二区三区国产馆 | 日本免费看 | 咪咪爱网友自拍 | 末发育xxxxx仙踪林 | 欧美 变态 另类 人妖班 | 蜜桃在线| 欧美性理论片在线观看片免费 | 日本玖玖视频 | 男人午夜禁片在线观看 | 色婷婷综合久久久中文字幕 | 青青草国产精品久久碰 | 大又大又粗又爽女人毛片 | 婷婷日韩| 男人都懂www深夜免费网站 | 国内揄拍国内精品久久 | pron在线观看 | 三上悠亚精品专区久久 | 91精品国产高清久久久久久91 | 青青青国产手机在线播放 | 国产三级精品播放 | 高h细节肉爽文办公室 | 国产剧情在线播放 | 清纯唯美 亚洲 | 国产欧美二区三区 | 欧美日韩精品乱国产 | 欧美日韩一区二区中文字幕视频 | 大ji巴好好爽好深网站 | 毛片99| 叛佛 作者满栀小说免费阅读 |