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是真的坑。

相关推荐
雪豹阿伟1 小时前
16.C# —— 委托,委托实例,多播委托,内置委托,泛型委托
c#·上位机
小满Autumn1 小时前
WPF 依赖属性速查手册
笔记·c#·wpf·上位机·mvvm
JaydenAI1 小时前
[MAF预定义ChatClient中间件-09]MessageInjectingChatClient-赋予工具消息注入的能力
ai·c#·agent·maf·ichatclient
Xin_ye100862 小时前
C# 零基础到精通教程 - WPF 深度专题:3D 图形与视觉增强
开发语言·c#·wpf
Chris _data4 小时前
并发单词频率统计器 - 从零到完整实现(C# 实战)
开发语言·c#
iCxhust13 小时前
C# 命令行指令 查看二进制文件
开发语言·单片机·嵌入式硬件·c#·proteus·微机原理·8088单板机
雪豹阿伟16 小时前
15.C# —— 多接口,泛型方法,泛型效率、泛型类和泛型接口、泛型约束
c#·上位机
影寂ldy16 小时前
C# const 常量 / readonly 只读 / static readonly
java·开发语言·c#