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

相关推荐
samble38 分钟前
从零搭建灌装监控系统(十三):报警系统设计,生命周期与通知
c#·wpf·mvvm·modbus·工业控制
miofly3 小时前
GitHub 今日推荐|SCSKiller:游戏着色器预编译消除卡顿
开源·c#·github
周杰伦fans17 小时前
8GB显存下模型量化实战指南
人工智能·后端·c#
samble19 小时前
从零搭建灌装监控系统(十二):配置系统,原子写入与容错
c#·wpf·mvvm·modbus·工业控制
流形填表1 天前
题库去重实战:基于题干指纹的重复题清理
开发语言·c#
开开心心就好1 天前
以图搜图找重复图片,本地工具离线就能用
javascript·智能手机·ffmpeg·c#·ocr·word·音视频
QQ_21696290961 天前
基于C#(Asp.net)电竞陪玩信息管理系统的设计与实现
java·大数据·spring boot·微信小程序·c#·云计算·asp.net
未来之窗软件服务2 天前
C# 截图源码支持自动保存-东方仙盟
c#·仙盟创梦ide·东方仙盟·电脑工具
UIU1142 天前
-7 / 2 在 C 里是 -3,在 Python 里是 -4,谁算错了?
c++·学习·c#
wflynn2 天前
GitHub 今日推荐|REDox:64 位 token 表示结构化数据,内存占用降 70% 支持多格式互转
开源·c#·github