Winform实现多语言切换

1.实现效果

2.实现思路

  1. 使用JSON格式存放多语言翻译的文本,以窗体名称. Translations.json进行文件的命名。
  2. 将翻译方法写入基类窗体Load(frmBaseForm_Load)事件中,找到翻译文件即可进行翻译;未找到文件,则遍历窗体上控件得到需要翻译的文本,然后使用腾讯机器翻译API/自定义离线翻译工具API进行翻译的调用形成翻译文件,然后进行翻译。

3.具体实现

  1. 多语言下拉按钮

使用json文件进行配置

json 复制代码
{
  "中文": "zh",
  "English": "en",
  "italiano": "it",
  "español": "es",
  "ภาษาไทย": "th"
}

然后在xml里面存放当前选择的是哪种语言

初始化状态栏的时候添加

c# 复制代码
 string jsonString = System.IO.File.ReadAllText(new SkinInfoHeleper().GetAbsolutePath() + "\\" + "Language.json");

 languageList = JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonString) ?? new Dictionary<string, string>();

 foreach (var item in languageList)
 {
     index++;

     DevExpress.XtraBars.BarButtonItem barButtonItem = new DevExpress.XtraBars.BarButtonItem();

     barButtonItem.Caption = item.Key;
     barButtonItem.Name = "barButtonlanguageItemAuto" + index.ToString();
     barButtonItem.Id = 999 + index;
     barButtonItem.ItemClick += BarButtonItem_ItemClick; ;
     this.barLanguageChange.LinksPersistInfo.AddRange(new DevExpress.XtraBars.LinkPersistInfo[] {
 new DevExpress.XtraBars.LinkPersistInfo(barButtonItem) });
 }
  1. 工具类代码

LanguageInjector :翻译窗体类

c# 复制代码
 public static class LanguageInjector
 {

     //public static ProjectManager ProMgr = new ProjectManager();
     /// <summary>
     /// 为指定窗体应用对应语言的文本
     /// 读取文件:{窗体名}.Translations.json
     /// 文件格式
     /// </summary>
     public static void ApplyLanguage(Form form, string cultureName)
     {
         if (form == null || string.IsNullOrWhiteSpace(cultureName))
             return;

         // 1. 构造文件路径:Form1.Translations.json
         string fileName = $"{form.GetType().Name}.Translations.json";
         string jsonPath = Path.Combine(Application.StartupPath.Replace("\\bin", "\\Language"), fileName);

         // 2. 检查文件是否存在
         if (!System.IO.File.Exists(jsonPath))
         {
             // 文件不存在,跳过,不报错
             return;
         }

         try
         {
             //这里是为了防止修改了之后在数据库中还存在着手动修改的数据,在替换的时候优先使用手动修改的数据
             var dataalist = GetTranslateData(cultureName, form.GetType().Name);
             //var dataalist = new List<Fnd_Translation>();//不使用数据可以反注释这句话,或者删除相关的dataalist代码
             // 3. 读取整个嵌套 JSON 文件
             string json = System.IO.File.ReadAllText(jsonPath, Encoding.UTF8);
             var allTranslations = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, string>>>(json);

             // 4. 根据 cultureName 获取对应语言的翻译字典
             Dictionary<string, string> langMap = null;

             if (allTranslations != null && allTranslations.ContainsKey(cultureName))
             {
                 langMap = allTranslations[cultureName];
             }
             else
             {
                 // 5. 回退到 zh-CN(默认中文)
                 if (allTranslations != null && allTranslations.ContainsKey("zh-CN"))
                 {
                     langMap = allTranslations["zh-CN"];
                 }
                 else
                 {
                     // 6. 无任何语言数据,直接返回
                     return;
                 }
             }

             //7.遍历窗体所有控件,应用翻译
             foreach (Control control in GetAllControls(form))
             { // 跳过 ComboBox,避免干扰 SelectedIndex
                 //if (control is ComboBox)
                 //    continue;
                 if (control.Name == "")
                     continue;

                 if (control.Name == "lbl")
                 {
                     continue;
                 }

                 // 跳过输入类控件(用户可编辑的)
                 if (control is DevExpress.XtraEditors.TextEdit || control is DevExpress.XtraEditors.ComboBoxEdit)
                     continue;

                 if (control is DevExpress.XtraGrid.GridControl gridControl)
                 {
                     // 获取主视图和所有从属视图
                     var views = new List<DevExpress.XtraGrid.Views.Base.BaseView>();

                     if (gridControl.MainView != null)
                         views.Add(gridControl.MainView);

                     if (gridControl.ViewCollection != null)
                     {
                         foreach (DevExpress.XtraGrid.Views.Base.BaseView view in gridControl.ViewCollection)
                         {
                             if (view != gridControl.MainView && !views.Contains(view))
                                 views.Add(view);
                         }
                     }

                     // 遍历每个视图,如果是 GridView,则翻译其列标题
                     foreach (DevExpress.XtraGrid.Views.Base.BaseView view in views)
                     {
                         if (view is DevExpress.XtraGrid.Views.Grid.GridView gridView)
                         {
                             foreach (DevExpress.XtraGrid.Columns.GridColumn column in gridView.Columns)
                             {
                                 // 构造列的唯一键:{GridControl名称}.{列名称}.Caption
                                 string columnKey = $"{column.Name}.Caption";

                                 if (dataalist.FirstOrDefault(a => a.LABEL_NAME == columnKey) != null)
                                 {
                                     column.Caption = dataalist.FirstOrDefault(a => a.LABEL_NAME == columnKey).TRANSLATION_TEXT;
                                 }
                                 else
                                 {

                                     if (langMap.TryGetValue(columnKey, out string translatedCaption))
                                     {
                                         column.Caption = translatedCaption;
                                     }
                                 }
                             }
                         }
                     }
                 }

                 if (control is UCBtnExt btn)
                 {
                     var keyWord = $"{control.Name}.Text";
                     if (dataalist.FirstOrDefault(a => a.LABEL_NAME == keyWord) != null)
                     {
                         btn.BtnText = dataalist.FirstOrDefault(a => a.LABEL_NAME == keyWord).TRANSLATION_TEXT;
                     }
                     else
                     {
                         btn.BtnText = langMap[$"{control.Name}.Text"];
                     }
                 }

                 string key = $"{control.Name}.Text";
                 if (langMap.TryGetValue(key, out string translatedText))
                 {
                     if (dataalist.FirstOrDefault(a => a.LABEL_NAME == key) != null)
                     {
                         control.Text = dataalist.FirstOrDefault(a => a.LABEL_NAME == key).TRANSLATION_TEXT;
                     }
                     else
                     {
                         control.Text = translatedText;
                     }
                 }


             }

             // 7. 遍历窗体自身及其所有控件,应用翻译
             //var allControls = new List<Control> { form }; // 先加入窗体自身
             //allControls.AddRange(GetAllControls(form));

             //foreach (Control control in allControls)
             //{
             //    if (string.IsNullOrEmpty(control.Name))
             //        continue;

             //    // 跳过输入类控件(用户可编辑的)
             //    if (control is DevExpress.XtraEditors.TextEdit || control is DevExpress.XtraEditors.ComboBoxEdit)
             //        continue;



             //    string key = $"{control.Name}.Text";
             //    if (langMap.TryGetValue(key, out string translatedText))
             //    {
             //        control.Text = translatedText;
             //    }
             //}
         }
         catch (Exception ex)
         {
             // 翻译文件格式错误或读取失败,静默处理,不影响程序
             System.Diagnostics.Debug.WriteLine($"加载翻译文件失败: {jsonPath},错误: {ex.Message}");
         }
     }

     /// <summary>
     /// 递归获取所有控件(包括嵌套容器中的)
     /// </summary>
     private static IEnumerable<Control> GetAllControls(Control parent)
     {
         foreach (Control c in parent.Controls)
         {
             yield return c;
             if (c.HasChildren)
                 foreach (var child in GetAllControls(c))
                     yield return child;
         }
     }
   }

TencentCloudTranslator:腾讯机工具类 要使用Nuget包下载TencentCloud.Tmt

C# 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using TencentCloud.Common;
using TencentCloud.Common.Profile;
using TencentCloud.Tmt.V20180321;
using TencentCloud.Tmt.V20180321.Models;

public class TencentCloudTranslator
{

    private readonly TmtClient _client;

    // 构造函数:初始化客户端(建议在应用启动时单例使用)
    public TencentCloudTranslator(string region = "ap-chongqing")
    {
        // 仅用于本地调试,生产环境绝对禁止!
        Environment.SetEnvironmentVariable("TENCENTCLOUD_SECRET_ID", "E7nFQct");
        Environment.SetEnvironmentVariable("TENCENTCLOUD_SECRET_KEY", "Kk5H4cofOvIWgill");

        var secretId = Environment.GetEnvironmentVariable("TENCENTCLOUD_SECRET_ID");
        var secretKey = Environment.GetEnvironmentVariable("TENCENTCLOUD_SECRET_KEY");

        if (string.IsNullOrEmpty(secretId) || string.IsNullOrEmpty(secretKey))
        {
            throw new InvalidOperationException("请在环境变量中配置 TENCENTCLOUD_SECRET_ID 和 TENCENTCLOUD_SECRET_KEY。");
        }

        var cred = new Credential
        {
            SecretId = secretId,
            SecretKey = secretKey
        };

        var httpProfile = new HttpProfile
        {
            Endpoint = "tmt.tencentcloudapi.com"
        };

        var clientProfile = new ClientProfile
        {
            HttpProfile = httpProfile
        };

        _client = new TmtClient(cred, region, clientProfile);
    }

    /// <summary>
    /// 翻译文本
    /// </summary>
    /// <param name="text">要翻译的原文</param>
    /// <param name="sourceLang">源语言代码,如 "zh"(中文)</param>
    /// <param name="targetLang">目标语言代码,如 "en"(英文)、"ja"(日文)等</param>
    /// <param name="projectId">项目ID,默认为 0</param>
    /// <returns>翻译后的文本</returns>
    public string Translate(string text, string sourceLang = "zh", string targetLang = "en", long projectId = 0)
    {
        if (string.IsNullOrWhiteSpace(text))
            throw new ArgumentException("待翻译文本不能为空。", nameof(text));

        try
        {
            var req = new TextTranslateRequest
            {
                SourceText = text,
                Source = sourceLang,
                Target = targetLang,
                ProjectId = projectId
            };

            TextTranslateResponse resp = _client.TextTranslateSync(req);
            return resp.TargetText;
        }
        catch (Exception ex)
        {
            // 建议记录日志而不是仅输出到控制台
            Console.WriteLine($"翻译失败: {ex}");
            throw; // 或返回 null / 默认值,根据业务需求决定
        }
    }

    /// <summary>
    /// 翻译多条文本
    /// </summary>
    /// <param name="text">要翻译的原文</param>
    /// <param name="sourceLang">源语言代码,如 "zh"(中文)</param>
    /// <param name="targetLang">目标语言代码,如 "en"(英文)、"ja"(日文)等</param>
    /// <param name="projectId">项目ID,默认为 0</param>
    /// <returns>翻译后的文本</returns>
    public List<string> batchTranslate(List<string> textList, string sourceLang = "zh", string targetLang = "en", long projectId = 0)
    {
        if (textList.Count == 0)
            throw new ArgumentException("待翻译文本不能为空。");
        try
        {
            var req = new TextTranslateBatchRequest
            {
                SourceTextList = textList.ToArray(),
                Source = sourceLang,
                Target = targetLang,
                ProjectId = projectId
            };

            TextTranslateBatchResponse resp = _client.TextTranslateBatchSync(req);
            return resp.TargetTextList.ToList();
        }
        catch (Exception ex)
        {
            // 建议记录日志而不是仅输出到控制台
            Console.WriteLine($"翻译失败: {ex}");
            throw; // 或返回 null / 默认值,根据业务需求决定
        }
    }
}

TranslateExistingJson:中文模板工具类

c# 复制代码
public static class TranslateExistingJson{   
    public static void AutoTranslateExistingJson(string FromName)   
    {      
        string fileName = $"{FromName}.Translations.json";       

        string filePath = Path.Combine(Application.StartupPath.Replace("\\bin", "\\Language"), fileName);

        if (!File.Exists(filePath))   
        {       
            MessageBox.Show($"未找到翻译模板文件:{fileName}\n请先执行"导出翻译模板"功能。", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);      
            return;   
        } 

        // 1. 读取现有 JSON    

        string jsonContent = File.ReadAllText(filePath);    
        var allTranslations = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, string>>>(jsonContent);​
            if (!allTranslations.TryGetValue("zh", out var sourceDict) || sourceDict.Count == 0)    
            { 
                MessageBox.Show("模板中缺少 zh 数据或为空。", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; 
            }

        string jsonString = System.IO.File.ReadAllText(new SkinInfoHeleper().GetAbsolutePath() + "\\" + "Language.json");

        var targetLanguages = JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonString) ?? new Dictionary<string, string>();

        // 2. 定义目标语言映射(.NET 文化名 → 腾讯云语言代码)
        //var targetLanguages = new Dictionary<string, string>
        //    {
        //        { "en-US", "en" },
        //        { "fr-FR", "fr" },
        //        { "ru-RU", "ru" },
        //        { "ja-JP", "ja" },
        //        { "es-ES", "es" }
        //        // 可按需扩展
        //    };

        // 3. 初始化翻译器
        TencentCloudTranslator translator;
        try
        {
            translator = new TencentCloudTranslator();
        }
        catch (Exception ex)
        {
            MessageBox.Show($"翻译器初始化失败:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            return;
        }

        // 4. 提取键和值(保持顺序一致)
        var keys = sourceDict.Keys.ToList();
        var texts = sourceDict.Values.ToList();

        // 5. 对每种语言进行翻译并合并
        foreach (var lang in targetLanguages)
        {
            string cultureName = lang.Value;     // 如 "en-US"
            string tmtCode = lang.Value;       // 如 "en"

            if (allTranslations.ContainsKey(cultureName))
            {
                // 可选:跳过已存在的语言,或覆盖
                // 这里选择跳过以避免重复翻译
                continue;
            }

            try
            {
                var translatedList = translator.batchTranslate(texts, "zh", tmtCode);
                var translatedDict = new Dictionary<string, string>();

                for (int i = 0; i < keys.Count; i++)
                {
                    translatedDict[keys[i]] = translatedList[i];
                }

                allTranslations[cultureName] = translatedDict;
            }
            catch (Exception ex)
            {
                MessageBox.Show($"翻译到 {cultureName} 时出错:{ex.Message}", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        // 6. 保存回文件
        string updatedJson = JsonConvert.SerializeObject(allTranslations, Newtonsoft.Json.Formatting.Indented);
        File.WriteAllText(filePath, updatedJson);

        //MessageBox.Show($"多语言翻译已完成并更新到:{filePath}", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
    }

    /// <summary>
    /// 获取语言列表
    /// </summary>
    /// <returns></returns>
    public static Dictionary<string, string> GetLanguageList()
    {
        string jsonString = System.IO.File.ReadAllText(new SkinInfoHeleper().GetAbsolutePath() + "\\" + "Language.json");

        var languageList = JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonString) ?? new Dictionary<string, string>();

        return languageList;
    }

    /// <summary>
    /// 获取语言对应的国家
    /// </summary>
    public static string GetLanguageContry(string language)
    {
        string jsonString = System.IO.File.ReadAllText(new SkinInfoHeleper().GetAbsolutePath() + "\\" + "Language.json");

        var languageList = JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonString) ?? new Dictionary<string, string>();
        return languageList[language];
    }

    /// <summary>
    /// 是否存在窗体的语言文件
    /// </summary>
    /// <param name="FromName"></param>
    /// <returns></returns>
    public static bool IsExistFromNameLanguage(string FromName)
    {

        string fileName = $"{FromName}.Translations.json";
        string filePath = Path.Combine(Application.StartupPath.Replace("\\bin", "\\Language"), fileName);

        if (!File.Exists(filePath))
        {
            return false;
        }
        else
        {
            return true;
        }
    }

    public static string GetTranslationFileString(string FromName)
    {

        string fileName = $"{FromName}.Translations.json";
        string filePath = Path.Combine(Application.StartupPath.Replace("\\bin", "\\Language"), fileName);

        string jsonContent = File.ReadAllText(filePath);
        return jsonContent;
    }

    public static string GetFormFilePath(string FromName)
    {
        string fileName = $"{FromName}.Translations.json";
        string filePath = Path.Combine(Application.StartupPath.Replace("\\bin", "\\Language"), fileName);
        return filePath;
    }
}
  1. 基类窗体Load事件中调用

    c# 复制代码
     private void frmBaseForm_Load(object sender, EventArgs e)
     {
         this.OnInitBar(null, null, null);
         this.InitBarTools();
    
         var lamg = LicenseXMLHelper.GetItemValue("Languages");
         //获取语言实际的国家
         var language = TranslateExistingJson.GetLanguageContry(lamg);
         LanguageInjector.ApplyLanguage(this, language);
     }
  2. 翻译主体框架

    C# 复制代码
    /// <summary>
    /// 找到需要翻译的所有控件 一定要在页面加载之后进行 
    /// </summary>
    private void GetNeedTrant(List<ZR.Model.Privilege.MenuInfo> PublicList)
    {
        // 1. 收集当前窗体所有控件的 Text
        var controlTexts = new Dictionary<string, string>();
    
        // 遍历窗体中所有控件,提取所有控件的 Text 属性
        foreach (Control ctrl in LicenseXMLHelper.GetAllControls(this))
        {
            if (!string.IsNullOrEmpty(ctrl.Text))
            {
                controlTexts[$"{ctrl.Name}.Text"] = ctrl.Text;
            }
            //如果是列表
            if (ctrl is DevExpress.XtraGrid.GridControl gridControl)
            {
                // 遍历该 GridControl 的所有视图(包括主视图和从属视图)
                var views = new List<DevExpress.XtraGrid.Views.Base.BaseView>();
                views.Add(gridControl.MainView); // 主视图
    
                // 如果是主从表结构,获取所有从属视图
                if (gridControl.ViewCollection != null)
                {
                    foreach (DevExpress.XtraGrid.Views.Base.BaseView view in gridControl.ViewCollection)
                    {
                        if (view != gridControl.MainView && !views.Contains(view))
                        {
                            views.Add(view);
                        }
                    }
                }
    
                // 遍历每个视图,如果是 GridView,则提取其列
                foreach (DevExpress.XtraGrid.Views.Base.BaseView view in views)
                {
                    if (view is DevExpress.XtraGrid.Views.Grid.GridView gridView)
                    {
                        foreach (DevExpress.XtraGrid.Columns.GridColumn column in gridView.Columns)
                        {
                            if (!string.IsNullOrEmpty(column.Caption))
                            {
                                controlTexts[$"{column.Name}.Caption"] = column.Caption;
                            }
                        }
                    }
                }
            }
    
            staticItems = LicenseXMLHelper.GetAllBarStaticItems(this.barManager1).ToList();
            foreach (var item in staticItems)
            {
                controlTexts[$"{item.Name}.Caption"] = item.Caption;
            }
    
            var toolItems = LicenseXMLHelper.GetItemsRecursive(this.contextMenuStrip1.Items);
    
            foreach (var item in toolItems)
            {
                controlTexts[$"{item.Name}.Text"] = item.Text;
            }
    
            foreach (var item in PublicList)
            {
    
                var formName = item.LinkForm.ClassName.Split('.').Last();
                if (!string.IsNullOrWhiteSpace(formName)) 
                {
    
                    controlTexts[$"{formName}.Text"] = item.Caption;
                }
            }
    
        }
    
        // 2. 包装成嵌套结构:{ "zh-CN": { ... } }
        var nestedTranslations = new Dictionary<string, Dictionary<string, string>>
            {
                { "zh", controlTexts } // 关键:用 zh-CN 作为外层键
            };
    
        // 3. 输出到文件:Form1.Translations.json
        string fileName = $"{this.Name}.Translations.json";
        string filePath = Path.Combine(Application.StartupPath.Replace("\\bin", "\\Language"), fileName);
    
        //需要重新主体框架翻译就解开下面两行的注释  这句话很重要
        //File.WriteAllText(filePath, JsonConvert.SerializeObject(nestedTranslations, Newtonsoft.Json.Formatting.Indented));
        //TranslateExistingJson.AutoTranslateExistingJson(this.Name);
        //加载xml配置文件中定义的当前语言,此方法仅在这个地方有效果,其他地方都不能完成语言的切换
        LoadMainThenTrantslate();
    
    }
            /// <summary>
            /// 所有页面加载完成之后翻译主体框架
            /// </summary>
            private void LoadMainThenTrantslate()
            {
    
                var lamg = LicenseXMLHelper.GetItemValue("Languages");
                //获取语言实际的国家
                var language = TranslateExistingJson.GetLanguageContry(lamg);
                //应用翻译
                ApplyLanguage(this, language);
            }

    需要在打开新窗口的代码下面加上调用ApplyLanguageXtab调用,用于Table页的切换

    C# 复制代码
    if (!string.IsNullOrEmpty(FromInfo.DllPath) && !string.IsNullOrEmpty(FromInfo.ClassName))
    {
        string dllPath = FromInfo.DllPath; //模块路径
        string formName = FromInfo.ClassName; //类名
        Assembly outerAsm = Assembly.LoadFrom(dllPath);
        Type outerForm = outerAsm.GetType(formName, false);//找到指定窗口
        frmBaseForm form = (Activator.CreateInstance(outerForm) as frmBaseForm);//转换成窗体类
        form.Text = FromInfo.ClassTitle;
        form.MdiParent = this;
        form.CanClose = FromInfo.CanClose;
        form.Line.DESCRIPTIONS = FromInfo.LineName;
        form.Dot.DESCRIPTIONS = FromInfo.PointName;
        form.FormType = FromInfo.FormType;
        form.LookAndFeel.UseDefaultLookAndFeel = true;
        form.Show();
    
        //如果不存在语言包则调用语言包生成
        if (!TranslateExistingJson.IsExistFromNameLanguage(form.Name))
        {
    
            LicenseXMLHelper.ExportTranslations(form);
        }
    
        var lamg = LicenseXMLHelper.GetItemValue("Languages");
        //获取语言实际的国家
        var language = TranslateExistingJson.GetLanguageContry(lamg);
        //加载页面之后重新翻译Tab名称
        ApplyLanguageXtab(this,language);  
    
    }
    C# 复制代码
    /// <summary>
    /// 翻译Xtab页面
    /// </summary>
    /// <param name="form"></param>
    /// <param name="cultureName"></param>
    private void ApplyLanguageXtab(Form form,string cultureName) 
    {
    
        if (form == null || string.IsNullOrWhiteSpace(cultureName))
            return;
    
        // 1. 构造文件路径:Form1.Translations.json
        string fileName = $"{form.GetType().Name}.Translations.json";
        string jsonPath = Path.Combine(Application.StartupPath.Replace("\\bin", "\\Language"), fileName);
    
        // 2. 检查文件是否存在
        if (!File.Exists(jsonPath))
        {
            // 文件不存在,跳过,不报错
            return;
        }
    
        try
        {
            // 3. 读取整个嵌套 JSON 文件
            string json = File.ReadAllText(jsonPath, Encoding.UTF8);
            var allTranslations = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, string>>>(json);
    
            // 4. 根据 cultureName 获取对应语言的翻译字典
            Dictionary<string, string> langMap = null;
    
            if (allTranslations != null && allTranslations.ContainsKey(cultureName))
            {
                langMap = allTranslations[cultureName];
            }
            else
            {
                // 5. 回退到 zh-CN(默认中文)
                if (allTranslations != null && allTranslations.ContainsKey("zh-CN"))
                {
                    langMap = allTranslations["zh-CN"];
                }
            }
    
            foreach (var items in xtraTabbedMdiManager1.Pages.ToList())
            {
                var control = items.MdiChild;
    
                string key = $"{control.Name}.Text";
                if (langMap.TryGetValue(key, out string translatedText))
                {
                    control.Text = translatedText;
                }
            }
    
    
        }
        catch (Exception ex)
        {
    
        }
     }
相关推荐
light blue bird17 天前
产线多并发客户端指令操作场景组件
jvm·oracle·.net·winform
初级代码游戏1 个月前
套路化编程 C# winform 自适应缩放布局
开发语言·c#·winform·自动布局·自动缩放
Traced back1 个月前
WinForms 线程安全三剑客详解
安全·c#·winform
PfCoder1 个月前
WinForm真入门(23)---PictureBox 控件详细用法
开发语言·windows·c#·winform
PfCoder1 个月前
C#中定时器之System.Timers.Timer
c#·.net·visual studio·winform
时光追逐者1 个月前
使用 NanUI 快速创建具有现代用户界面的 WinForm 应用程序
ui·c#·.net·winform
老骥伏枥~1 个月前
WinForm中的DataGridView 控件
winform
刘欣的博客2 个月前
c# winform 控件dock 停造位置、摆放顺序问题
c#·winform·dock停靠问题
故事不长丨2 个月前
C#log4net详解:从入门到精通,配置、实战与框架对比
c#·.net·wpf·log4net·日志·winform·日志系统