[连载]《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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/399090.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【JavaScript】apply和call的区别在哪?

我在一开始看到javascript的函数apply和call时,非常的模糊,看也看不懂,最近在网上看到一些文章对apply方法和call的一些示例,总算是看的有点眉目了,在这里我做如下笔记,希望和大家分享.. 如有什么不对的或者说法不明确的地方希望读者多多提一些意见,以便共同提高.. 主要我是要解…

php js动态显示系统时间,PHP+JS动态显示服务器时间

摘要&#xff1a;JS默认只能获取当前系统时间&#xff0c;若想获取服务器时间&#xff0c;必须加上后端语言配合&#xff0c;PHPJS获取服务器端时间代码&#xff1a;运行结果&#xff1a;2017-4-4 15:...JS默认只能获取当前系统时间&#xff0c;若想获取服务器时间&#xff0c;…

SQL中的事物【转】

来源于&#xff1a;http://www.cnblogs.com/zhuifengnianshao/archive/2010/11/24/1886939.html事务&#xff08;Transaction&#xff09;是并发控制的单位&#xff0c;是用户定义的一个操作序列。这些操作要么都做&#xff0c;要么都不做&#xff0c;是一个不可分割的工作单位…

Mybaitis JdbcType 和javaType

2019独角兽企业重金招聘Python工程师标准>>> MyBatis 通过包含的jdbcType类型 BIT FLOAT CHAR TIMESTAMP OTHER UNDEFINEDTINYINT REAL VARCHAR BINARY BLOB NVARCHARSMALLINT DOUBLE …

装箱和拆箱(js的问题)

装箱&#xff1a;基本数据类型 -> 引用数据类型 var num 123; var numObj new Number(123);console.log(typeof num) // number console.log(typeof numObj) // object 拆箱&#xff1a;引用数据类型 -> 基本数据类型 var numObj new Number(123);console.log(numO…

php文件缓存代码,php文件缓存实例代码

php教程文件缓存实例代码缓存在实际使用当中应用很广泛&#xff0c;可以减轻对服务器数据库教程的访问&#xff0c;提高运行速度。目前很多cms内容管理系统中频繁使用缓存机制来提高系统运行的效率cache.php 代码如下&#xff1a;php代码/*用户需要事先定义的常量&#xff1a;_…

[架构] 分布式和集群的区别

一次在群里面看到群友们在讨论这个的区别&#xff0c;看了他们发表的言论&#xff0c;觉得很有道理&#xff0c;很通俗易懂&#xff0c;就当做学习的笔记记录在这里&#xff1a; 用两个例子看清楚分布式和集群的区别&#xff1a; 例子1&#xff1a; 如果一个任务由10个子任务组…

JQuery.lazyload 图片延迟加载

1.引入 jquery.lazyload.js 2. 延时加载的方式 <script type"text/javascript">   $(function() {     $("img").lazyload({     effect : "fadeIn"    });   });   </script> 3. 把阀值设置成200 意思就是当图…

如何把UIView转成UIImage,解决模糊失真问题

最近工作中&#xff0c;遇到一个需求&#xff0c;需要把一个UIView对象转成UIImage对象显示。经过网络搜索&#xff0c;找到如下答案&#xff1a; ?12345678-(UIImage*)convertViewToImage:(UIView*)v{CGSize s v.bounds.size;UIGraphicsBeginImageContext(s);[v.layer rende…

php数据趋势曲线,数据曲线图怎么做

数据曲线图怎么做&#xff1f;1、在电脑桌面上&#xff0c;新建一个excel文件(操作过程即为点击右键&#xff0c;在选项中选择“新建”选项&#xff0c;然后再选择“excel文件”&#xff0c;即可成功新建excel文件了)2、双击将新建的excel文件打开&#xff0c;输入你需要统计制…

ceph 分布式存储安装

[rootlocalhost ~]# rm -rf /etc/yum.repos.d/*.repo 下载阿里云的base源 [rootlocalhost ~]# wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo [rootlocalhost ~]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/r…

基本技能

1、分析Android游戏积分机制、付费机制、存档机制2、游戏破解嵌入特定页面&#xff0c;页面涵盖logo&#xff0c;url外链等基础内容3、破解游戏呈现无限金币、免费道具、无敌等表现方式1、精通汇编语言、Java或C/C语言&#xff0c;对逆向工程有浓厚兴趣2、有代表作品3、 熟练掌…

STM32学习之路-SysTick的应用(时间延迟)

开发板&#xff1a;奋斗V5 好~ 菜B要来搞实验了.. 前面已经说了SysTick的工作原理什么的了,这里就不说了.. 先来做第一个实验&#xff1a; 盗自奋斗的样例,嘿嘿, 用SysTick产生1ms的基准时间,产生中断,每秒闪烁一次(LED1 V6) &#xff08;1&#xff09;外围时钟初始化&#xf…

centos akonadi mysql,MySQL数据库之在CentOS7上安装MySQL5.7

本文主要向大家介绍了MySQL数据库之在CentOS7上安装MySQL5.7 &#xff0c;通过具体的内容向大家展现&#xff0c;希望对大家学习MySQL数据库有所帮助。获取RPM包# wget https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm列出RPM包里都有哪些文件# rpm -q…

usaco-crypt1-pass

这个想了半天&#xff0c;终于过了&#xff1a; /* ID: qq104801 LANG: C TASK: crypt1 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h>void debug_dummy() {return; }int n; int d[10];int numlen(int x) { …

凡事预则立(Beta)

听说——凡事预则立 吸取之前alpha冲刺的经验教训&#xff0c;也为了这次的beta冲刺可以更好更顺利地进行&#xff0c;更是为了迎接我们的新成员玮诗。我们开了一次组内会议&#xff0c;进行beta冲刺的规划。 上一张我们的合照&#xff1a; 具体会议议程如下&#xff1a; 1、讨…

tomcat 指定的服务未安装(总结验证)

如果你的tomcat是解压版的&#xff0c;解压版的话要环境配置一、jdk环境变量一定要配置对&#xff0c;如果配置不对也会出现此提示 1&#xff0c;新建变量名&#xff1a;JAVA_HOME&#xff0c;变量值&#xff1a;C:\Program Files\Java\jdk1.7.02&#xff0c;打开PATH&#xff…

java url 授权,Spring MVC框架 - 基本认证之URL 授权认证

[导读]为控制器添加注解是非常简单的&#xff0c;但这往往并不是最可行的方案。有时候&#xff0c;我们会想要完全控制授权功能。为控制器添加注解是非常简单的,但这往往并不是最可行的方案。有时候,我们会想要完全控制授权功能。移除Secured 注解,我们将会采用一种更好的方案。…

什么原因成就了一位优秀的程序员?(转)

这些年我曾和很多程序员一起工作&#xff0c;他们之中的一些人非常厉害&#xff0c;而另一些人显得平庸。不久前因为和一些技术非常熟练的程序员工作感觉很愉快&#xff0c;我花了一些时间在考虑我佩服他们什么呢&#xff1f;什么原因让优秀的程序员那么优秀&#xff0c;糟糕的…

用Vue.js开发一个电影App的前端界面

我们要构建一个什么样的App&#xff1f; 我们大多数人使用在线流媒体服务&#xff08;如Netflix&#xff09;观看我们最喜欢的电影或者节目。这篇文章将重点介绍如何通过使用vue.js 2 建立一个类似风格的电影流媒体WEB交互界面&#xff08;见上图&#xff09;。 最终的产品可以…