最近Winform项目想添加多语言支持, 之前一直没关注, 这几天翻阅了很多分享, 终于整理出了一些头绪, 应用到程序中也实现了多语言的支持, 现整理下以备忘.
具体原理就不说了, 网上太多, 这里只罗列实现步骤:
首先, 创建一个对话框:
添加两个按钮, 分别进行命名,这是正常的创建流程, 中文状态下的界面;
然后我们要编辑英文状态下的界面, 在窗体属性, 注意是窗体属性页面, 将Localizable属性设置为true, 并将Language属性由默认设置为英语, 英语有好多选项, 英语全球, 英语美国等等, 直接选择英语即可, 如下图 :
此时你需要修改界面各个控件的文本内容为对应的英文, 修改完毕如下图所示:
保存下你会发现在解决方案资源管理器中该窗体下多了一个.en.resx为后缀的文件:
打开看下:
里面有按钮控件的英文列表, 那么打开默认的resx文件看看呢?
也生成了对应的中文资源, 这些都是VS自动生成的, 后期维护也相对方便了, 这样控件方面的多语言到这里也就实现的差不多了, 那么怎么进行中英文切换呢?
一、在程序运行前调用
Thread.CurrentThread.CurrentUICulture = new CultureInfo(“en”或者“zh-CN”);
那么后续创建的窗体就不需要理会了,窗体以及控件会自动应用语言环境;
二、程序运行时的切换
调用下面LoadLanguage方法,Settings.Defautl.Language是自定义的语言设置,值为“en”或“zh-CN”或者其他语言缩写;
/// <summary>
/// 指定窗体载入语言
/// </summary>
/// <param name="aForm"></param>
/// <param name="aFormType"></param>
public static void LoadLanguage(Form aForm)
{
if (aForm != null)
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo(Settings.Default.Language);
ComponentResourceManager resources = new ComponentResourceManager(aForm.GetType());
resources.ApplyResources(aForm, "$this");
LoadingControls(aForm, resources);
}
}
/// <summary>
///
/// </summary>
/// <param name="aControl"></param>
/// <param name="aResources"></param>
private static void LoadingControls(Control aControl, ComponentResourceManager aResources)
{
if (aControl is MenuStrip)
{
//将资源与控件对应
aResources.ApplyResources(aControl, aControl.Name);
MenuStrip menu = (MenuStrip)aControl;
if (menu.Items.Count > 0)
{
foreach (ToolStripMenuItem item in menu.Items)
{
//遍历菜单
Loading(item, aResources);
}
}
}
foreach (Control ctrl in aControl.Controls)
{
aResources.ApplyResources(ctrl, ctrl.Name);
LoadingControls(ctrl, aResources);
}
}
/// <summary>
/// 遍历菜单
/// </summary>
/// <param name="aItem">菜单项</param>
/// <param name="aResources">语言资源</param>
private static void Loading(ToolStripMenuItem aItem, ComponentResourceManager aResources)
{
if (aItem is ToolStripMenuItem)
{
aResources.ApplyResources(aItem, aItem.Name);
if (aItem.DropDownItems.Count > 0)
{
foreach (ToolStripMenuItem item in aItem.DropDownItems)
{
Loading(item, aResources);
}
}
}
}
这样就可以直接在程序运行过程中进行语言切换;
窗体控件的多语言支持已经记录完毕,这方面其实还不是很麻烦,麻烦的其实是程序在运行过程中各种自定义的提示字符串的多语言支持,如果里面提示信息过多,那真是头疼,而且用上述的办法还无法实现,下面介绍一种跟上述类似的方法管理多语言字符串的定义:
添加两个资源文件,一个为LanguageStrings.resx,这里将存储默认的中文语言资源,另一个为LanguageStrings.en.resx,这里将存储英文语言资源,如下图:
打开这两个文件,会发现跟窗体的资源管理页面一样,在两个资源中添加自定义的语句,如下图所示:
中英文资源的名称一定要是对应一样的,不允许包含标点符号,因为是中文开发环境,名称可以写为中文描述,这样在编写提示时也方便理解维护,资源编写完了,如何去调用呢?使用下面这个方法:
/// <summary>
/// 资源管理器
/// </summary>
private static readonly ResourceManager mResources = new ResourceManager("CarEyeClient.Utils.LanguageStrings", typeof(MultiLanguage).Assembly);
/// <summary>
/// 获取多语言对应的字符串
/// </summary>
/// <param name="aKey"></param>
/// <param name="aForm">字符串所在窗体, 线程间操作时需要传入窗体</param>
/// <returns></returns>
public static string GetString(string aKey, Form aForm = null)
{
string newStr = null;
if (aForm != null)
{
aForm.InvokeIfRequired((form) => newStr = mResources.GetString(aKey));
}
else
{
newStr = mResources.GetString(aKey);
}
if (string.IsNullOrEmpty(newStr)
&& !string.IsNullOrEmpty(aKey))
{
return aKey;
}
return newStr;
}
在UI线程中调用时可忽略aForm参数,资源将会根据设置的语言环境自动查找关键字对应的中英文字符串,但是这种方法在非UI线程中调用会发生调用无效的情况,所以增加了aForm参数,在非UI线程调用该方法时传入对应窗体对象即可,窗体进行委托调用即可获取正确的中英文资源。
至此,Winform的多语言环境基本就完善了,运行截图: