C#如何实现中英文快速切换

首先定义一个中英文切换的静态类 然后在类里面写如下代码

cs 复制代码
/// <summary>
/// 静态语言管理类,用于全局管理应用程序的语言切换、资源加载和事件通知。
/// 通过设置 Language 属性可动态切换中英文等语言,并自动更新界面资源。
/// </summary>
public static class LanguageModel
{
    /// <summary>
    /// 组件资源管理器,用于访问本地化资源(如字符串、图片等)。
    /// 默认加载英文资源(Resources.Resource_en)。
    /// </summary>
    public static ComponentResourceManager crm = new ComponentResourceManager(typeof(Resources.Resource_en));

    /// <summary>
    /// 中文切换事件委托。当语言切换为中文时触发订阅的方法。
    /// 示例:LanguageModel.ChineseChangeAction += UpdateUIForChinese;
    /// </summary>
    public static Action ChineseChangeAction { get; set; }

    /// <summary>
    /// 英文切换事件委托。当语言切换为英文时触发订阅的方法。
    /// 示例:LanguageModel.EnglishChangeAction += UpdateUIForEnglish;
    /// </summary>
    public static Action EnglishChangeAction { get; set; }

    /// <summary>
    /// 私有字段,存储当前语言代码(默认值为 "zh")。
    /// 有效值:"zh"(中文)、"en"(英文)。
    /// </summary>
    private static string language = "zh";

    /// <summary>
    /// 当前应用程序语言属性。
    /// 获取或设置语言时,会自动切换资源文件和触发对应事件。
    /// </summary>
    /// <example>
    /// 切换到中文:LanguageModel.Language = "zh";
    /// 切换到英文:LanguageModel.Language = "en";
    /// </example>
    public static string Language
    {
        // 获取当前语言代码
        get => language;

        // 设置语言并执行切换逻辑
        set
        {
            // 更新当前语言
            language = value;

            // 根据语言代码执行不同操作
            switch (value)
            {
                case "zh": // 中文
                    // 触发中文切换事件(如果已订阅)
                    ChineseChangeAction?.Invoke();

                    // 加载中文资源文件
                    crm = new ComponentResourceManager(typeof(Resources.Resource_zh));
                    break;

                case "en": // 英文
                    // 触发英文切换事件(如果已订阅)
                    EnglishChangeAction?.Invoke();

                    // 加载英文资源文件
                    crm = new ComponentResourceManager(typeof(Resources.Resource_en));
                    break;

                // 可扩展其他语言支持
                // default:
                //     throw new ArgumentException("Unsupported language code.");
            }
        }
    }
}

ComponentResourceManager 是 .NET Framework 中的一个类(位于 System.ComponentModel 命名空间),专门用于管理和访问本地化资源(如多语言文本、图片、图标等)。它在 WinForms 应用程序中尤其常见,用于动态加载不同语言的界面资源。

为什么用 typeof(Resources.Resource_xx)

  • 通过 typeof 指定资源文件的强类型类,确保编译器检查资源是否存在。

  • 资源文件会被编译成嵌入资源(Embedded Resource),运行时直接从程序集中加载。

如何使用

cs 复制代码
/// <summary>
/// 切换应用程序界面语言为中文,并更新所有已打开的窗体资源
/// </summary>
private void ChineseChange()
{
    // 1. 设置当前线程的区域性(Culture)为中文
    // CurrentCulture 影响数字、日期等格式
    Thread.CurrentThread.CurrentCulture = new CultureInfo("zh");
    
    // 2. 设置当前线程的UI区域性(UICulture)为中文
    // CurrentUICulture 影响资源文件加载(如界面文字)
    Thread.CurrentThread.CurrentUICulture = new CultureInfo("zh");

    // 3. 遍历应用程序中所有已打开的窗体
    foreach (Form f in Application.OpenForms)
    {
        // 4. 对每个窗体应用新的资源设置
        // 这会根据当前UICulture重新加载对应语言的资源
        ApplyResource(f);
    }
}
  1. 区域性设置

    • CurrentCulture:影响数字、日期、货币等区域性相关格式

    • CurrentUICulture:专门控制界面元素的本地化资源加载

cs 复制代码
/// <summary>
/// 根据当前线程的区域性设置,为指定控件应用对应的语言资源
/// </summary>
/// <param name="control">要应用资源的目标控件</param>
public void ApplyResource(Control control)
{
    // 1. 根据当前线程的区域性设置选择合适的资源文件
    switch (Thread.CurrentThread.CurrentCulture.Name)
    {
        case "en": // 英文环境
            // 初始化英文资源管理器,加载英文资源文件
            crm = new ComponentResourceManager(typeof(Resources.Resource_en));
            break;
        case "zh": // 中文环境
            // 初始化中文资源管理器,加载中文资源文件
            crm = new ComponentResourceManager(typeof(Resources.Resource_zh));
            break;
        default:   // 其他未明确支持的语言环境
            // 默认使用中文资源作为回退方案
            crm = new ComponentResourceManager(typeof(Resources.Resource_zh));
            break;
    }

    // 2. 调用applyControl方法实际应用资源到控件
    // 参数1:控件的类型名称(用于资源查找)
    // 参数2:目标控件实例
    applyControl(control.GetType().Name, control);
}
  1. 区域性判断

    • 使用Thread.CurrentThread.CurrentCulture.Name获取当前线程的区域性名称

    • 根据不同的区域性代码选择对应的资源文件

  2. 资源管理器初始化

    • 每种语言对应一个独立的资源文件(如Resource_en.resxResource_zh.resx

    • 使用ComponentResourceManager来管理特定语言的资源

  3. 默认处理

    • 当遇到未明确支持的语言时,默认使用中文资源

    • 这是一种常见的回退机制设计

  4. 资源应用

    • 最终调用applyControl方法将资源实际应用到控件

    • 传递控件的类型名称用于资源键值查找

cs 复制代码
/// <summary>
/// 递归应用资源到控件及其子控件
/// </summary>
/// <param name="topName">父控件名称路径(用于资源键前缀)</param>
/// <param name="control">当前要处理的控件对象</param>
private void applyControl(string topName, Control control)
{
    // 处理表格布局面板(递归处理子控件)
    if (control.GetType() == typeof(TableLayoutPanel))
    {
        // 遍历所有子控件
        foreach (Control ctl in control.Controls)
        {
            // 应用资源:资源键格式为"父控件名.子控件名"
            crm.ApplyResources(ctl, topName + "." + ctl.Name, Thread.CurrentThread.CurrentCulture);
            // 递归处理子控件
            applyControl(topName, ctl);
        }
    }
    // 处理分组框(递归处理子控件)
    else if (control.GetType() == typeof(GroupBox))
    {
        foreach (Control ctl in control.Controls)
        {
            crm.ApplyResources(ctl, topName + "." + ctl.Name, Thread.CurrentThread.CurrentCulture);
            applyControl(topName, ctl);
        }
    }
    // 处理UI面板(自定义面板控件,递归处理子控件)
    else if (control.GetType() == typeof(UIPanel))
    {
        foreach (Control ctl in control.Controls)
        {
            crm.ApplyResources(ctl, topName + "." + ctl.Name, Thread.CurrentThread.CurrentCulture);
            applyControl(topName, ctl);
        }
    }
    // 处理UI标题面板(自定义控件,递归处理子控件)
    else if (control.GetType() == typeof(UITitlePanel))
    {
        foreach (Control ctl in control.Controls)
        {
            crm.ApplyResources(ctl, topName + "." + ctl.Name, Thread.CurrentThread.CurrentCulture);
            applyControl(topName, ctl);
        }
    }
    // 处理UI分组框(自定义控件,递归处理子控件)
    else if (control.GetType() == typeof(UIGroupBox))
    {
        foreach (Control ctl in control.Controls)
        {
            crm.ApplyResources(ctl, topName + "." + ctl.Name, Thread.CurrentThread.CurrentCulture);
            applyControl(topName, ctl);
        }
    }
    // 处理普通面板(递归处理子控件)
    else if (control.GetType() == typeof(Panel))
    {
        foreach (Control ctl in control.Controls)
        {
            crm.ApplyResources(ctl, topName + "." + ctl.Name, Thread.CurrentThread.CurrentCulture);
            applyControl(topName, ctl);
        }
    }
    // 处理状态栏控件(特殊处理ToolStripItem集合)
    else if (control.GetType() == typeof(StatusStrip))
    {
        var statusStrip = (StatusStrip)control;
        // 遍历状态项(非标准Control类型)
        foreach (ToolStripItem ctl in statusStrip.Items)
        {
            crm.ApplyResources(ctl, topName + "." + ctl.Name, Thread.CurrentThread.CurrentCulture);
        }
    }
    // 处理选项卡控件(递归处理各TabPage)
    else if (control.GetType() == typeof(TabControl))
    {
        var Tab = (TabControl)control;
        foreach (TabPage ctl in Tab.TabPages)
        {
            crm.ApplyResources(ctl, topName + "." + ctl.Name, Thread.CurrentThread.CurrentCulture);
            applyControl(topName, ctl);
        }
    }
    // 处理单个选项卡页(递归处理子控件)
    else if (control.GetType() == typeof(TabPage))
    {
        var Page = (TabPage)control;
        foreach (Control ctl in Page.Controls)
        {
            crm.ApplyResources(ctl, topName + "." + ctl.Name, Thread.CurrentThread.CurrentCulture);
            applyControl(topName, ctl);
        }
    }
    // 处理数据网格视图(特殊处理列标题)
    else if (control.GetType() == typeof(DataGridView))
    {
        var dataGridView = (DataGridView)control;
        foreach (DataGridViewColumn ctl in dataGridView.Columns)
        {
            crm.ApplyResources(ctl, topName + "." + ctl.Name, Thread.CurrentThread.CurrentCulture);
        }
    }
    // 处理特定窗体类型(需要特殊处理窗体资源)
    else if (control.GetType() == typeof(frmAbout) || control.GetType() == typeof(FrmDB) || control.GetType() == typeof(frmLogin) || control.GetType() == typeof(FrmMainView) || control.GetType() == typeof(FrmSingleView)
        || control.GetType() == typeof(frmSystemSet) || control.GetType() == typeof(frmTCB) || control.GetType() == typeof(frmUserMananger) || control.GetType() == typeof(frmSystemChannelSet))
    {
        // 先应用窗体自身的资源(使用控件名作为资源键)
        crm.ApplyResources(control, control.Name, Thread.CurrentThread.CurrentCulture);
        // 处理窗体所有子控件(使用窗体名作为新的topName)
        foreach (Control ctl in control.Controls)
        {
            crm.ApplyResources(ctl, topName + "." + ctl.Name, Thread.CurrentThread.CurrentCulture);
            // 递归时使用窗体名作为新的topName
            applyControl(control.Name, ctl);
        }
    }
    // 默认处理(普通控件)
    else
    {
        // 直接应用资源(使用父控件名.当前控件名作为资源键)
        crm.ApplyResources(control, topName + "." + control.Name, Thread.CurrentThread.CurrentCulture);
    }
}
相关推荐
19H1 小时前
Flink-Source算子状态恢复分析
c#·linq
Hello.Reader2 小时前
Redis 延迟监控深度指南
数据库·redis·缓存
ybq195133454312 小时前
Redis-主从复制-分布式系统
java·数据库·redis
枯萎穿心攻击3 小时前
响应式编程入门教程第二节:构建 ObservableProperty<T> — 封装 ReactiveProperty 的高级用法
开发语言·unity·c#·游戏引擎
Eiceblue5 小时前
【免费.NET方案】CSV到PDF与DataTable的快速转换
开发语言·pdf·c#·.net
好奇的菜鸟5 小时前
如何在IntelliJ IDEA中设置数据库连接全局共享
java·数据库·intellij-idea
tan180°5 小时前
MySQL表的操作(3)
linux·数据库·c++·vscode·后端·mysql
满昕欢喜5 小时前
SQL Server从入门到项目实践(超值版)读书笔记 20
数据库·sql·sqlserver
Hello.Reader7 小时前
Redis 延迟排查与优化全攻略
数据库·redis·缓存
简佐义的博客8 小时前
破解非模式物种GO/KEGG注释难题
开发语言·数据库·后端·oracle·golang