• [连载]《C#通讯(串口和网络)框架的设计与实现》- 13.中英文版本切换设计


    目       录

    第十三章     中英文版本切换设计... 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:504547114@qq.com

    QQ:504547114

    .NET开发技术联盟:54256083

    文档下载:http://pan.baidu.com/s/1pJ7lZWf

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

  • 相关阅读:
    11月21日
    11月20日
    11月19日
    11月18日
    11月17日
    11月15日
    图文教程:在Mac上搭建Titanium的iOS开发环境
    经验
    IT术语的正确读法
    NSLog( @"%@", i );
  • 原文地址:https://www.cnblogs.com/lsjwq/p/5104412.html
Copyright © 2020-2023  润新知