C#实现简单的多语言,如英文不存在则利用翻译api翻译

1. 语言资源文件设计

Languages目录下创建不同语言的文件,两种格式根据个人喜好任选一种即可:

  • JSON格式:zh_CN.jsonen_US.json
  • XML格式:zh_CN.xmlen_US.xml

JSON文件结构示例:

{
  "MainForm_Text": "工具",
  "lbl_Language_Text": "语言",
  "grp_Rdo_Text": "模式选择",
  "rdo_StrDeDup_Text": "字符串去重",
  "rdo_ClearNote_Text": "清理注释",
  "rdo_FilpBigSmall_Text": "bin文件翻转大小端",
  "btn_SelectFile_Text": "选择文件",
  "btn_Convert_Text": "转换",
  "btn_FilpBigSmall_Text": "翻转多个文件大小端"
}

XML文件结构示例:

<?xml version="1.0" encoding="utf-8"?>
<Language>
  <String Key="MainForm_Text">工具</String>
  <String Key="lbl_Language_Text">语言</String>
  <String Key="grp_Rdo_Text">模式选择</String>
  <String Key="rdo_StrDeDup_Text">字符串去重</String>
  <String Key="rdo_ClearNote_Text">清理注释</String>
  <String Key="rdo_FilpBigSmall_Text">bin文件翻转大小端</String>
  <String Key="btn_SelectFile_Text">选择文件</String>
  <String Key="btn_Convert_Text">转换</String>
  <String Key="btn_FilpBigSmall_Text">翻转多个文件大小端</String>
</Language>

2. Language类实现

Language类负责加载和解析语言文件,支持JSON和XML两种格式,当英文文件不存在时,自动使用百度翻译API生成,BaiduTransHelper类代码见《C#调用百度翻译API,实现百度翻译帮助类》

public class Language
{
    public string MainForm_Text { get; private set; }
    public string lbl_Language_Text { get; private set; }
    public string grp_Rdo_Text { get; private set; }
    public string rdo_StrDeDup_Text { get; private set; }
    public string rdo_ClearNote_Text { get; private set; }
    public string rdo_FilpBigSmall_Text { get; private set; }
    public string btn_SelectFile_Text { get; private set; }
    public string btn_Convert_Text { get; private set; }
    public string btn_FilpBigSmall_Text { get; private set; }

    public Language(string language)
    {
        // 优先使用JSON格式
        if (File.Exists($"./Languages/{language}.json"))
        {
            JsonLoad(language);
        }
        // 其次使用XML格式
        else if (File.Exists($"./Languages/{language}.xml"))
        {
            XmlLoad(language);
        }
        else if (language == "en_US")
        {
            // 英文文件不存在,尝试从中文文件生成
            if (File.Exists($"./Languages/zh_CN.json"))
            {
                GenerateEnglishFromChinese("json");
                JsonLoad(language);
            }
            else if (File.Exists($"./Languages/zh_CN.xml"))
            {
                GenerateEnglishFromChinese("xml");
                XmlLoad(language);
            }
        }
    }

    private void JsonLoad(string language)
    {
        try
        {
            Dictionary<string, string> dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(
                File.ReadAllText($"./Languages/{language}.json")
            );
            foreach (var item in dict)
            {
                BindLanguageText(item.Key, item.Value);
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }           
    }

    private void XmlLoad(string language)
    {
        try
        {
            string path = AppDomain.CurrentDomain.BaseDirectory + "Languages\\" + language + ".xml";
            XDocument doc = XDocument.Load(path);
            XElement xeles = doc.Root;
            foreach (XElement item in xeles.Elements())
            {
                if (item.Name.ToString() == "String")
                {
                    BindLanguageText(item.Attribute("Key").Value, item.Value);
                }
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

    private void GenerateEnglishFromChinese(string format)
    {
        try
        {
            Dictionary<string, string> dictZh = new Dictionary<string, string>();
            
            if (format == "json")
            {
                dictZh = JsonConvert.DeserializeObject<Dictionary<string, string>>(
                    File.ReadAllText($"./Languages/zh_CN.json")
                );
            }
            else if (format == "xml")
            {
                XDocument doc = XDocument.Load($"./Languages/zh_CN.xml");
                XElement xeles = doc.Root;
                foreach (XElement item in xeles.Elements())
                {
                    if (item.Name.ToString() == "String")
                    {
                        dictZh.Add(item.Attribute("Key").Value, item.Value);
                    }
                }
            }

            var results = BaiduTransHelper.Translation(dictZh.Values, "zh", "en");
            int i = 0;
            Dictionary<string, string> dictEn = new Dictionary<string, string>();
            foreach (var key in dictZh.Keys)
            {
                dictEn.Add(key, results[i++].dst);
            }

            if (format == "json")
            {
                File.WriteAllText($"./Languages/en_US.json", 
                    JsonConvert.SerializeObject(dictEn, Formatting.Indented), 
                    Encoding.UTF8);
            }
            else if (format == "xml")
            {
                XDocument doc = new XDocument(
                    new XDeclaration("1.0", "utf-8", "yes"),
                    new XElement("Language")
                );
                foreach (var item in dictEn)
                {
                    doc.Root.Add(new XElement("String", new XAttribute("Key", item.Key), item.Value));
                }
                doc.Save($"./Languages/en_US.xml", SaveOptions.None);
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

    public void BindLanguageText(string key, string value)
    {
        switch (key)
        {
            case "MainForm_Text":
                MainForm_Text = value;
                break;
            case "lbl_Language_Text":
                lbl_Language_Text = value;
                break;
            case "grp_Rdo_Text":
                grp_Rdo_Text = value;
                break;
            case "rdo_StrDeDup_Text":
                rdo_StrDeDup_Text = value;
                break;
            case "rdo_ClearNote_Text":
                rdo_ClearNote_Text = value;
                break;
            case "rdo_FilpBigSmall_Text":
                rdo_FilpBigSmall_Text = value;
                break;
            case "btn_SelectFile_Text":
                btn_SelectFile_Text = value;
                break;
            case "btn_Convert_Text":
                btn_Convert_Text = value;
                break;
            case "btn_FilpBigSmall_Text":
                btn_FilpBigSmall_Text = value;
                break;
            default:
                break;
        }
    }
}

3. 多语言切换实现

通过实现ISetUILanguage接口,在主窗体中实现语言切换功能:

public partial class MainForm : Form, ISetUILanguage
{
    public void SetUITextLanguage(string languageStr)
    {
        Language language = new Language(languageStr);
        this.Text = language.MainForm_Text;
        lbl_Language.Text = language.lbl_Language_Text;
        grp_Rdo.Text = language.grp_Rdo_Text;
        rdo_StrDeDup.Text = language.rdo_StrDeDup_Text;
        rdo_ClearNote.Text = language.rdo_ClearNote_Text;
        rdo_FilpBigSmall.Text = language.rdo_FilpBigSmall_Text;
        btn_SelectFile.Text = language.btn_SelectFile_Text;
        btn_Convert.Text = language.btn_Convert_Text;
        btn_FilpBigSmall.Text = language.btn_FilpBigSmall_Text;
    }

    private void cmb_Language_SelectedValueChanged(object sender, EventArgs e)
    {
        string languageStr = cmb_Language.SelectedValue.ToString();
        if (!string.IsNullOrEmpty(languageStr))
        {
            SetUITextLanguage(languageStr);
        }
    }
}

4. 语言文件自动加载

在窗体初始化时,自动加载所有语言文件到下拉框:

public MainForm()
{
    InitializeComponent();
    #region 获取支持的语言赋入language下拉框
    List<string> languagesStr = new List<string>();
    foreach (string item in Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory + "Languages\\"))
    {
        string fileName = Path.GetFileNameWithoutExtension(item);
        if (!languagesStr.Contains(fileName))
        {
            languagesStr.Add(fileName);
        }
    }            
    cmb_Language.DataSource = languagesStr;
    #endregion
}

总结

通过本文介绍的多语言实现方案,我们可以构建支持多语言的应用程序,并在英文语言文件不存在时,利用百度翻译API自动生成英文语言文件。同时,该方案支持JSON和XML两种语言资源文件格式,为开发者提供了更多的选择。

在实际应用中,我们可以根据具体需求对这些方案进行调整和扩展,以满足不同场景下的多语言支持需求。例如,可以扩展支持更多语言,或者优化翻译质量,以提供更好的用户体验。

posted @ 2026-03-16 10:41  (*_^)?  阅读(6)  评论(0)    收藏  举报