第十三章 中英文版本切换设计

王朝学院·作者佚名  2016-08-28
窄屏简体版  字體: 小  |  中  |  大  |  超大  

目 录

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

[flash=500,400]http://s1.knowsky.com/20160211/gp1mbaxxlj145.png[/flash]

Key的定义有两种方式,第一种:窗体命名.控件命名,可以对窗体的控件统一改变显示的语言信息。第二种:直接定义关键字,可以对提示信息、状态信息等单独词条改变显示的语言信息。Value就是最终要显示语言的具体内容,完全自定义。

13.3 语言管理类定义一个词条对应的可序列化的类。代码如下:[Serializable]

public class CultureItem

{

/// <summary>

/// 控件的级联ID,中间用"."分隔

/// </summary>

[XmlAttribute]

public string Key { set; get; }

/// <summary>

/// 中文或英文描述

/// </summary>

[XmlAttribute]

public string Value { set; get; }

}

定义一个设置语言属性的枚举。代码如下:public enum CultureLanguage

{

[EnumDescription("中文")]

Chinese,

[EnumDescription("英文")]

English

}

开发一个语言管理类库,本质上是根据语言配置文件对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

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航