分享兩種實(shí)現(xiàn)Winform程序的多語(yǔ)言支持的多種解決方案第5/5頁(yè)
作者:夢(mèng)在旅途 字體:[增加 減小] 類(lèi)型:轉(zhuǎn)載 時(shí)間:2017-02-03 我要評(píng)論
MyStyleTreeView:
public partial class MyStyleTreeView : MyTreeView, IMultiLanguageContainerControl { static Dictionary<string, string> LanDict = new Dictionary<string, string>(); Dictionary<object, string> nodeTexts = new Dictionary<object, string>(); public MyStyleTreeView() { nodeTexts.Clear(); this.DrawMode = TreeViewDrawMode.OwnerDrawText; this.AfterExpand += MyStyleTreeView_AfterExpand; } private void MyStyleTreeView_AfterExpand(object sender, TreeViewEventArgs e) { this.Refresh(); } protected override void OnDrawNode(DrawTreeNodeEventArgs e) { IntPtr hdc = e.Graphics.GetHdc(); Graphics g = Graphics.FromHdc(hdc); g.SmoothingMode = SmoothingMode.AntiAlias; Font nodeFont = e.Node.NodeFont; if (nodeFont == null) nodeFont = this.Font; Color foreColor = Color.Black; Color backColor = this.BackColor; if (this.ContainsFocus && (e.Node.IsSelected || (e.State & TreeNodeStates.Focused) != 0)) { foreColor = Color.White; backColor = Color.FromArgb(51, 153, 255); } string txt = e.Node.Text; if (!string.IsNullOrWhiteSpace(txt) && !DesignMode) { if (LanDict.ContainsKey(e.Node.Text)) { txt = LanDict[e.Node.Text]; } else { if (ChildrenChanged != null) { ChildrenAddedEventArgs args = new ChildrenAddedEventArgs(); args[e.Node] = txt; ChildrenChanged(this, args); LanDict[txt] = args[e.Node]; txt = args[e.Node]; args = null; } else { string langText = LanguageHelper.GetLanguageText(txt); LanDict[txt] = langText; txt = langText; } } } SizeF txtSize = g.MeasureString(txt, Font); Rectangle txtRect = new Rectangle(e.Bounds.X, e.Bounds.Y, (int)txtSize.Width + 2, e.Bounds.Height); using (SolidBrush sb = new SolidBrush(backColor)) { g.FillRectangle(sb, txtRect); } TextRenderer.DrawText( g, txt, Font, txtRect, foreColor, TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter); e.Graphics.ReleaseHdc(hdc); g.Dispose(); } [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Dictionary<object, string> DefaultLangTexts { get { nodeTexts.Clear(); foreach (TreeNode item in this.Nodes) { if (LanDict.ContainsKey(item.Text)) { item.Text = LanDict[item.Text]; } else { nodeTexts.Add(item, item.Text); } GetNodeText(item); } return nodeTexts; } } [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Dictionary<object, string> CurrentLangTexts { get { try { Dictionary<object, string> dict = new Dictionary<object, string>(); Dictionary<object, string> defaultLangTexts = DefaultLangTexts; foreach (var item in defaultLangTexts) { if (LanDict.ContainsKey(item.Value)) { dict[item.Key] = LanDict[item.Value]; } else { dict[item.Key] = ""; } } return dict; } catch (Exception) { return null; } } set { if (System.Threading.Thread.CurrentThread.CurrentUICulture.Name != "zh-CHS") { foreach (var item in value) { if (LanDict.ContainsKey(nodeTexts[item.Key])) { LanDict[nodeTexts[item.Key]] = item.Value; } else { LanDict.Add(nodeTexts[item.Key], item.Value); } } } } } public Control this[string ctrlName] { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } } public void SetItemCurrentLangText(string ctrlName, string langText) { if (this.Nodes[ctrlName] != null) this.Nodes[ctrlName].Text = langText; } private void GetNodeText(TreeNode node) { if (node.Nodes.Count == 0) { return; } foreach (TreeNode tn in node.Nodes) { if (LanDict.ContainsKey(tn.Text)) { tn.Text = LanDict[tn.Text]; } else { nodeTexts.Add(tn, tn.Text); } GetNodeText(tn); } } [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public event EventHandler<ChildrenAddedEventArgs> ChildrenChanged; }
二次封裝這些控件的目的是: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)換公共類(lèi),與方案一原理相同,但相對(duì)方案一要簡(jiǎn)單很多,代碼如下:
public class LanguageHelper { #region 控件內(nèi)容簡(jiǎn)繁體轉(zhuǎn)換 /// <summary> /// 設(shè)置控件的語(yǔ)言 /// </summary> /// <param name="parent"></param> public static void SetControlLanguageText(System.Windows.Forms.Control ctrl) { if (ctrl.HasChildren) { foreach (Control item in ctrl.Controls) { if (item is IMultiLanguageControl) { IMultiLanguageControl il = item as IMultiLanguageControl; string value = GetLanguageText(il.DefaultLangText); il.CurrentLangText = value; } if (item is IMultiLanguageContainerControl) { IMultiLanguageContainerControl lic = item as IMultiLanguageContainerControl; Dictionary<object, string> dic = new Dictionary<object, string>(); foreach (var v in lic.DefaultLangTexts) { dic.Add(v.Key, GetLanguageText(v.Value)); } lic.CurrentLangTexts = dic; lic.ChildrenChanged += (s, e) => { List<object> keyList = new List<object>(); foreach (var key in e.LangTexts.Keys) { keyList.Add(key); } keyList.ForEach(x => { e[x] = GetLanguageText(e[x]); }); keyList = null; }; } if (item.HasChildren) { SetControlLanguageText(item); } } } else { IMultiLanguageControl il = ctrl as IMultiLanguageControl; string value = GetLanguageText(il.DefaultLangText); il.CurrentLangText = value; } } /// <summary> /// 根據(jù)語(yǔ)言標(biāo)識(shí)符得到轉(zhuǎn)換后的值 /// </summary> /// <param name="languageFlag"></param> /// <param name="value"></param> /// <returns></returns> public static string GetLanguageText(string value) { string languageFlag = Thread.CurrentThread.CurrentUICulture.Name; if (value == null || value == string.Empty) { return value; } switch (languageFlag.ToUpper()) { case "ZH-CHT": { return ToTraditional(value); } default: { return ToSimplified(value); } } } /// <summary> /// 簡(jiǎn)體轉(zhuǎn)換為繁體 /// </summary> /// <param name="str">簡(jiǎn)體字</param> /// <returns>繁體字</returns> private static string ToTraditional(string str) { if (string.IsNullOrEmpty(str)) return str; return ChineseConverter.Convert(str, ChineseConversionDirection.SimplifiedToTraditional); } /// <summary> /// 繁體轉(zhuǎn)換為簡(jiǎn)體 /// </summary> /// <param name="str">繁體字</param> /// <returns>簡(jiǎn)體字</returns> private static string ToSimplified(string str) { if (string.IsNullOrEmpty(str)) return str; return ChineseConverter.Convert(str, ChineseConversionDirection.TraditionalToSimplified); } #endregion } Common.IsChsLanguage方法定義如下: public static bool IsChsLanguage() { return System.Threading.Thread.CurrentThread.CurrentUICulture.Name.Equals("zh-CHS", StringComparison.OrdinalIgnoreCase); }
多語(yǔ)言支持的容器類(lèi)控件的實(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è)試。