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

简介: 目       录 第十三章     中英文版本切换设计... 2 13.1        不用自带的资源文件的理由... 2 13.2        配置文件... 2 13.3        语言管理类... 3 13.4        应用管理类... 12 13.5        小结... 12   第十三章      中英文版本切换设计 13.1     不用自带的资源文件的理由      可以利用resx资源文件进行多语言设计,resx文件本身是kv类型的资源文件,设计好资源文件后,启动软件时可以通过CurrentCulture属性设置要显示的语言。

目       录

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

相关文章
|
3月前
|
监控 安全
从 Racket 语言出发,创新员工网络监控软件的框架
在数字化企业环境中,员工网络监控软件对于保障信息安全和提升效率至关重要。Racket 语言凭借其独特特性和强大功能,为开发创新的监控软件提供了新可能。通过捕获和分析网络数据包、记录员工网络活动日志,甚至构建复杂的监控框架,Racket 能够满足企业的定制化需求,为企业信息安全和管理提供强有力支持。未来,基于 Racket 的创新解决方案将不断涌现。
55 6
|
2月前
|
数据采集 存储 JSON
Python网络爬虫:Scrapy框架的实战应用与技巧分享
【10月更文挑战第27天】本文介绍了Python网络爬虫Scrapy框架的实战应用与技巧。首先讲解了如何创建Scrapy项目、定义爬虫、处理JSON响应、设置User-Agent和代理,以及存储爬取的数据。通过具体示例,帮助读者掌握Scrapy的核心功能和使用方法,提升数据采集效率。
145 6
|
3月前
|
机器学习/深度学习 人工智能
类人神经网络再进一步!DeepMind最新50页论文提出AligNet框架:用层次化视觉概念对齐人类
【10月更文挑战第18天】这篇论文提出了一种名为AligNet的框架,旨在通过将人类知识注入神经网络来解决其与人类认知的不匹配问题。AligNet通过训练教师模型模仿人类判断,并将人类化的结构和知识转移至预训练的视觉模型中,从而提高模型在多种任务上的泛化能力和稳健性。实验结果表明,人类对齐的模型在相似性任务和出分布情况下表现更佳。
87 3
|
3月前
|
安全 网络安全 区块链
网络安全与信息安全:构建数字世界的防线在当今数字化时代,网络安全已成为维护个人隐私、企业机密和国家安全的重要屏障。随着网络攻击手段的不断升级,从社交工程到先进的持续性威胁(APT),我们必须采取更加严密的防护措施。本文将深入探讨网络安全漏洞的形成原因、加密技术的应用以及提高公众安全意识的重要性,旨在为读者提供一个全面的网络安全知识框架。
在这个数字信息日益膨胀的时代,网络安全问题成为了每一个网民不可忽视的重大议题。从个人信息泄露到企业数据被盗,再到国家安全受到威胁,网络安全漏洞如同隐藏在暗处的“黑洞”,时刻准备吞噬掉我们的信息安全。而加密技术作为守护网络安全的重要工具之一,其重要性不言而喻。同时,提高公众的安全意识,也是防范网络风险的关键所在。本文将从网络安全漏洞的定义及成因出发,解析当前主流的加密技术,并强调提升安全意识的必要性,为读者提供一份详尽的网络安全指南。
|
4月前
|
存储 SQL 安全
网络安全与信息安全:守护数字世界的坚盾在这个高度数字化的时代,网络安全和信息安全已经成为个人、企业乃至国家安全的重要组成部分。本文将深入探讨网络安全漏洞、加密技术以及安全意识的重要性,旨在为读者提供一个全面的网络安全知识框架。
随着互联网技术的飞速发展,网络安全问题日益凸显。从个人信息泄露到企业数据被盗,再到国家安全受到威胁,网络安全事件层出不穷。本文将从网络安全漏洞的定义与分类入手,探讨常见的网络攻击手段;随后深入解析加密技术的原理及其在保护信息安全中的作用;最后强调提升公众与企业的安全意识的重要性,并提出具体的建议。通过综合运用这些知识点,我们可以更好地构建起一道道坚固的防线,守护我们的数字世界。
|
4月前
|
编解码 分布式计算 网络协议
Netty高性能网络框架(一)
Netty高性能网络框架(一)
|
1月前
|
机器学习/深度学习 算法 PyTorch
基于图神经网络的大语言模型检索增强生成框架研究:面向知识图谱推理的优化与扩展
本文探讨了图神经网络(GNN)与大型语言模型(LLM)结合在知识图谱问答中的应用。研究首先基于G-Retriever构建了探索性模型,然后深入分析了GNN-RAG架构,通过敏感性研究和架构改进,显著提升了模型的推理能力和答案质量。实验结果表明,改进后的模型在多个评估指标上取得了显著提升,特别是在精确率和召回率方面。最后,文章提出了反思机制和教师网络的概念,进一步增强了模型的推理能力。
66 4
基于图神经网络的大语言模型检索增强生成框架研究:面向知识图谱推理的优化与扩展
|
2月前
|
人工智能 自然语言处理
WebDreamer:基于大语言模型模拟网页交互增强网络规划能力的框架
WebDreamer是一个基于大型语言模型(LLMs)的网络智能体框架,通过模拟网页交互来增强网络规划能力。它利用GPT-4o作为世界模型,预测用户行为及其结果,优化决策过程,提高性能和安全性。WebDreamer的核心在于“做梦”概念,即在实际采取行动前,用LLM预测每个可能步骤的结果,并选择最有可能实现目标的行动。
75 1
WebDreamer:基于大语言模型模拟网页交互增强网络规划能力的框架
|
2月前
|
JSON 数据处理 Swift
Swift 中的网络编程,主要介绍了 URLSession 和 Alamofire 两大框架的特点、用法及实际应用
本文深入探讨了 Swift 中的网络编程,主要介绍了 URLSession 和 Alamofire 两大框架的特点、用法及实际应用。URLSession 由苹果提供,支持底层网络控制;Alamofire 则是在 URLSession 基础上增加了更简洁的接口和功能扩展。文章通过具体案例对比了两者的使用方法,帮助开发者根据需求选择合适的网络编程工具。
46 3
|
2月前
|
网络虚拟化
生成树协议(STP)及其演进版本RSTP和MSTP,旨在解决网络中的环路问题,提高网络的可靠性和稳定性
生成树协议(STP)及其演进版本RSTP和MSTP,旨在解决网络中的环路问题,提高网络的可靠性和稳定性。本文介绍了这三种协议的原理、特点及区别,并提供了思科和华为设备的命令示例,帮助读者更好地理解和应用这些协议。
96 4