C# 基于Json文件的多语言翻译功能简单实现
大致思路
将Json文件系列化储存在Dictionary中,再通过遍历指定控件及其子控件进行匹配替换。
注意:特殊需求(如:String中只局部翻译)以及个别控件(如:ToolStrip)需要自行添加处理方法,后续会详细讲解怎样去遍历特殊控件。。
具体实现及演示:
1、准备工作:
1.1 添加Json配置,网上有很多关于Json配置相关的文章不做详细讲解
C#使用json 点击工具 - NuGet包管理器 - 程序包管理控制台,输入下面命令: Install-Package Newtonsoft.Json 即可使用Newtonsoft.Json 包进行json操作 PM> Install-Package Newtonsoft.Json
1.2 对应的Json文件的编辑 :key翻译为value
英译中 Json配置
{
“Test”:“测试”,
“Language”:“语言”,
“Set”:“设置”,
“Chinese (default)”:“中文(默认)”,
“English”:“英文”
}
中译英 Json配置
{
“测试”:“Test”,
“语言”:“Language”,
“设置”:“Set”,
“中文(默认)”: “Chinese (default)”,
“英文”:“English”,
“英语”:“English”
}
1.3 向窗体放置各种常用控件以及对其相应文本进行编辑如图
2、自定义翻译类库
using Newtonsoft.Json; //Json文件序列化 using System.Windows.Forms; //控件遍历所需 using System.Text.RegularExpressions; //String处理 namespace Interpret { public class InterpretBase { //下文代码 } }
2.1 现有的资源加载方法
//定义字典用于储存Json配置文件资源 static Dictionary<string, string> resources = new Dictionary<string, string>(); /// <summary> /// 当前项目文件夹Debug\Language\参数文件夹 /// </summary> /// <param name="language">配置文件所在文件夹名</param> public static void LoadLanguage(string language = "") { if (string.IsNullOrEmpty(language)) { language = System.Threading.Thread.CurrentThread.CurrentUICulture.Name; } resources = new Dictionary<string, string>(); string dir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, string.Format("Language/{0}", language)); if (Directory.Exists(dir)) { var jaonFile = Directory.GetFiles(dir, "*.json", SearchOption.AllDirectories); foreach (string file in jaonFile) { LoadFile(file); } } } /// <summary> /// 配置文件加载 /// </summary> /// <param name="path">配置文件绝对路径(包括文件本身)</param> public static void LoadFile(string path) { var content = File.ReadAllText(path, Encoding.UTF8); if (!string.IsNullOrEmpty(content)) { var dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(content); foreach (string key in dict.Keys) { if (!resources.ContainsKey(key)) { resources.Add(key, dict[key]); } else resources[key] = dict[key]; } } }
2.2 普通控件的遍历(因为涉及其他相关 不能一一列举控件遍历,这里按Combox遍历,其他控件思路也是一样的)
/// <summary> /// 遍历翻译 窗体或控件及其子控件 /// </summary> /// <param name="control">需要翻译的控件或窗体</param> public static void InitLanguage(Control control) { SetControlLanguage(control); foreach (Control ctrl in control.Controls) { InitLanguage(ctrl); } //工具栏或者菜单动态构建窗体或者控件的时候,重新对子控件进行处理 control.ControlAdded += (sender, e) => { InitLanguage(e.Control); }; } /// <summary> /// 控件及子控件翻译 /// </summary> /// <param name="control">需要翻译的控件</param> public static void SetControlLanguage(Control control) { if (control is ComboBox) { ComboBox combox = control as ComboBox; string[] NewItems = new string[combox.Items.Count]; for (int i = 0; i < combox.Items.Count; i++) { if (resources.ContainsKey(combox.Items[i].ToString())) { NewItems[i] = resources[combox.Items[i].ToString()]; } else NewItems[i] = combox.Items[i].ToString(); } combox.Text = (resources.ContainsKey(combox.Text)) ? resources[combox.Text] : combox.Text; combox.Items.Clear(); combox.Items.AddRange(NewItems); } //control is 其他控件或者特殊控件 如:TreeView else if (control is TreeView) { //TreeView treeView = control as TreeView; //if (treeView.Nodes !=null) //{ //TreeViewNodes(treeView.Nodes); //} } else { control.Text = (resources.ContainsKey(control.Text)) ? resources[control.Text] : control.Text; } }
2.3 特殊控件的遍历思路(思路基本能满足绝大多数控件,由于详细涉及其他不能完整上传 深表歉意)
特殊控件的遍历思路其实跟普通控件的遍历是一样的 只是需要根据特殊控件不同情况去遍历的特殊属性进行判断翻译就行了(按TreeView为列讲解)
注:特殊控件不知道该遍历什么属性时可以去 InitializeComponent();窗体设计器生成的代码里查找 如图下
遍历datagridview的列
for (int i = 0; i < datagridview.ColumnCount; i++)
从而的到每一列,便可以对列头以及列头提示进行编辑
datagridview.Columns[i].HeaderText,
datagridview.Columns[i].ToolTipText
单元格遍历遇上雷同
下图为上文中 对其他控件或者特殊控件 TreeView的遍历
public static void TreeViewNodes(TreeNodeCollection Nodes) { for (int i = 0; i < Nodes.Count; i++) { if (Nodes[i].Text != null) Nodes[i].Text = (resources.ContainsKey(Nodes[i].Text)) ? resources[Nodes[i].Text] : Nodes[i].Text; if (Nodes[i].Nodes != null) { TreeViewNodes(Nodes[i].Nodes); } } }
以上便是对特殊控件的遍历,找到相应的属性,遍历在替换文本
2.4 添加特殊方法 供后文用
/// <summary> /// 局部匹配翻译,不存在则不翻译 /// </summary> /// <param name="text">需要翻译的正则公式</param> public static void PartInterpret(ref string text) { if (resources.Keys == null && resources.Keys.Count == 0) { MessageBox.Show("未添加资源文件,请及时确认或与工作人员联系", "提示!!"); return; } foreach (var item in resources) { if (text.Contains(item.Key)) { text = text.Replace(item.Key, item.Value); } } }
3 调用方式及特殊情况 结果展示
using IPret = Interpret.InterpretBase;//添加引用
string lang,oldLang; //语言设置 自行设置 private void button_Click(object sender, EventArgs e) { oldLang = lang;//用于判断当前语言是否与所需要语言一致 ,避免 lang = comboBox1.Text.ToString();//需要设置的语言 switch (lang) { case "中文(默认)": case "Chinese (default)": lang = "zh-CN"; break; case "英文": case "English": lang = "en-US"; break; default: lang = "zh-CN"; break; } if (oldLang != lang) { System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(lang); IPret.LoadLanguage(lang); IPret.InitLanguage(contextMenuStrip1); IPret.InitLanguage(this); #region ***********局部特殊内容翻译************ string s = label_Test.Text; IPret.PartInterpret(ref s); label_Test.Text = s; oldLang = lang; #endregion } }
实际效果图:
翻译前
翻译后
感谢阅览,第一次发文 若有不足之处,还望指出
今天的文章
c#jsonconvert_json如何使用分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/60564.html