在網上查閱很多方法,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 向表單放置各種常用控制元件以及對其相應文本進行編輯如圖1
: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();表單設計器生成的代碼里查找 如圖下雷同

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
}
}
實際效果圖:
翻譯前

翻譯后

感謝閱覽,第一次發文 若有不足之處,還望之處
uj5u.com熱心網友回復:
鼓勵并贊一個。
uj5u.com熱心網友回復:
uj5u.com熱心網友回復:
public static string PartInterpret(string text) // 一般不用ref string,而是回傳string
{
...
foreach (var item in resources)
{
if (text.Contains(item.Key))
{
text = text.Replace(item.Key, item.Value);
}
}
return text; // 一個函式,明確的輸入輸出,有利于閱讀。
}
uj5u.com熱心網友回復:
受教了 個人習慣問題 省幾行代碼
uj5u.com熱心網友回復:
謝謝 emmmmm
uj5u.com熱心網友回復:
難得奇文,贊
uj5u.com熱心網友回復:
uj5u.com熱心網友回復:
uj5u.com熱心網友回復:
感謝分享
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/120312.html
標籤:C#
上一篇:c# winform 如何獲取ActiveMQ 佇列的 剩余訊息
下一篇:c#入門倒計時
