Winform双语实现

文章目录

一、前言

好久没写了,记录一个winform双语实现。

之前使用Winform自带的 resx 实现双语,出现 控件跑位、各版本部对齐、翻译好的文本莫名丢失的情况。 一怒之下自己写了个实现。

二、思路

1、中文、英文两个Josn文件

2、读取helper

3、Form_Load里 给控制Text初始化

4、Program.cs里 先初始化 语言类型

发现少了一个存语言的,建一个cache.XML

三、语言的存储 cache.XML

1、建cache.xml

csharp 复制代码
<?xml version="1.0" encoding="utf-8"?>
<SystemConfigure>
	<Language>zh-CN</Language>
</SystemConfigure>

2、读写Helper CacheHelper.cs

csharp 复制代码
using Org.BouncyCastle.Ocsp;
using System;
using System.Diagnostics;
using System.Net.NetworkInformation;
using System.Xml;

/// <summary>
/// 配置状态缓存 读写类
/// </summary>
public class CacheHelper
{
    // 你的XML文件路径(按实际修改)
    private static readonly string XmlPath = Path.Combine(
        AppDomain.CurrentDomain.BaseDirectory,
        "LocalCache.xml"
    );

    public static string ReadLgg()
    {
        return ReadData("Language");
    }

    /// <summary>
    /// 修改并保存 FileSrcs 节点
    /// </summary>
    public static bool WriteLgg(string req)
    {
        return WriteData("Language", req);
    }

    /// <summary>
    /// 读取  节点
    /// </summary>
    public static string ReadData(string key)
    {
        try
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(XmlPath);
            return doc.SelectSingleNode("SystemConfigure/" + key).InnerText;
        }
        catch
        {
            return "";
        }
    }

    /// <summary>
    /// 修改并保存  节点
    /// </summary>
    public static bool WriteData(string key, string value)
    {
        try
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(XmlPath);
            doc.SelectSingleNode("SystemConfigure/" + key).InnerText = value;
            doc.Save(XmlPath);
            return true;
        }
        catch
        {
            return false;
        }
    }
}

切换语言的缓存:

CacheHelper.WriteLgg("zh-CN");

CacheHelper.WriteLgg("en-US");

四、双语实现

1、建JSON

csharp 复制代码
//lang.en-US.json
{
  "main": {
    "Text": "MainForm",
    "button1": "CN/EN",
    "label1": "This is a test",
  },
  "setting": {
    "Text": "Testfrom",
  }
}
//lang.zh-CN.json
{
  "main": {
    "Text": "主窗体",
    "button1": "中文 / English",
    "label1": "这是个测试",
  },
  "setting": {
    "Text": "测试窗体",
  }
}

2、建读取 LangHelper.cs

csharp 复制代码
using System;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;

public static class Lang
{
    // 顶级是main/setting,每个里面都是键值对,最简单的结构
    private static Dictionary<string, Dictionary<string, string>> _lang;
    public static string CurrentLang { get; private set; } = "zh-CN";

    public static void LoadLang(string langCode)
    {
        try
        {
            CurrentLang = langCode;
            string langFile = (langCode.ToLower().Contains("zh") ? "lang.zh-CN.json" : "lang.en-US.json");
            string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Language", langFile);

            // 用Newtonsoft.Json反序列化,最稳妥,不会有任何坑
            string json = File.ReadAllText(path);
            _lang = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, string>>>(json);
        }
        catch(Exception ex)
        {
            _lang = new Dictionary<string, Dictionary<string, string>>();
        }
    }

    public static string T(string key)
    {
        if (_lang == null || string.IsNullOrEmpty(key))
            return key;

        try
        {
            string[] parts = key.Split('.');
            if (parts.Length == 2 && _lang.TryGetValue(parts[0], out var section))
            {
                if (section.TryGetValue(parts[1], out var value))
                    return value;
            }
            return key;
        }
        catch
        {
            return key;
        }
    }
}

五、调用

1、Program.cs 缓存语言

csharp 复制代码
     static void Main()
     {
         ApplicationConfiguration.Initialize();

         // 读取本地保存的语言
         string lang = CacheHelper.ReadLgg();
         Lang.LoadLang(lang);
         //-end
         Application.Run(new frmMain());
     }

2、frmMain中

csharp 复制代码
   //刷新语言
	private void RefreshLang()
	{
    // 窗体标题
    this.Text = Lang.T("main.Text");
    // 按钮
    button1.Text = Lang.T("main.button1");
    // 标签
    label1.Text = Lang.T("main.label1");
    }
  //窗体控件 文本初始化  
  //记得在窗体事件里绑定Main_Load: Load += frmMain_Load;
 private void frmMain_Load(object sender, EventArgs e)
 {
     //初始化
     RefreshLang();
 }
 //中英切换事件
 private void button1_Click(object sender, EventArgs e)
 {
      string lgg = CacheHelper.ReadLgg();
		 if (lgg == "zh-CN") lgg = "en-US";
		 else lgg = "zh-CN";
		 CacheHelper.WriteLgg(lgg);
		 Lang.LoadLang(lgg);
		 RefreshLang();
 }

总结:

切换还是很丝滑的,没有VUE的 i18n 那么方便,但resx是真的坑。

相关推荐
唐青枫8 小时前
线程不是越多越快:C#.NET Thread 生命周期、同步与后台工作线程实战
c#·.net
唐青枫1 天前
别只会反射:C#.NET Emit 动态生成代码实战详解
c#·.net
咕白m6251 天前
.NET 环境下 Word 超链接批量提取方案
c#·.net
用户91721561902111 天前
C# 通信协议增量解析:用状态机处理半包和粘包
c#
小码编匠2 天前
C# 工控上位机必备:数据转换工具类与十个核心模块
后端·c#·.net
唐青枫4 天前
别再乱用 StartNew:C#.NET TaskFactory 任务调度实战详解
c#·.net
Artech4 天前
[MAF预定义的AIContextProvider-03]ChatHistoryMemoryProvider——赋予Agent从经验中学习的能力
ai·c#·agent·memory·maf
Scout-leaf6 天前
C#摸鱼实录——IoC与DI案例详解
c#
咕白m6256 天前
使用 C# 在 Excel 中应用多种字体样式
后端·c#
Artech6 天前
[MAF预定义的AIContextProvider-02]AgentSkillsProvider——将Agent Skills引入MAF
ai·c#·agent·agent skills·maf