看了几篇WPF 中使用ResXManager的文章:
小白请先阅读完毕再接着往下看。有经验的随意。
需要了解的一些类:
CultureInfo:
在代码中表示你的软件使用什么语言以及对应的资源文件。
System.Globalization.CultureInfo 类 - .NET | Microsoft Learn
ResourceManager
ResourceManager 是资源管理器,在代码中针对某一资源文件,根据键获取对应的值(资源文件就是键值对的形式)
ResourceManager 类 (System.Resources) | Microsoft Learn

大致步骤:
使用到的切换语言助手类大致如下:
cs
public class LanguageManager : INotifyPropertyChanged
{
/// <summary>
/// 资源
/// </summary>
private readonly ResourceManager _resourceManager;
/// <summary>
/// 懒加载
/// </summary>
private static readonly Lazy<LanguageManager> _lazy = new Lazy<LanguageManager>(() => new LanguageManager());
public static LanguageManager Instance => _lazy.Value;
public event PropertyChangedEventHandler PropertyChanged;
public LanguageManager()
{
//获取此命名空间下Resources的Lang的资源,Lang可以修改
_resourceManager = new ResourceManager("FluentVision.UI.Lang.lang", typeof(LanguageManager).Assembly);
}
/// <summary>
/// 索引器的写法,传入字符串的下标
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public string this[string name]
{
get
{
if (name == null)
{
throw new ArgumentNullException(nameof(name));
}
return _resourceManager.GetString(name);
}
}
public void ChangeLanguage(CultureInfo cultureInfo)
{
CultureInfo.CurrentCulture = cultureInfo;
CultureInfo.CurrentUICulture = cultureInfo;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("item[]")); //字符串集合,对应资源的值
}
}
语言切换:
cs
LanguageManager.Instance.ChangeLanguage(new CultureInfo("en"));
界面绑定:

代码中使用:

这里说一下几个关键点便于理解:
1.cultrueInfo和资源文件
资源文件命名规则为:文件名(自定义)+cultrueInfo.Name+.resx后缀名
如:
lang.resx 默认资源
lang.en.resx 英语资源
lang.zh-CN.resx 中文资源

这样命名应用程序代码会根据cultureInfo来确定从哪一个文件读取资源,这一部分是.Net内置的功能,确定了cultrueInfo就可以确定程序用到的资源文件。
创建新的对象:new CultureInfo("en"),就相当于宣布使用 lang.en.resx 这个文件。
2.加载默认资源文件

cs
_resourceManager = new ResourceManager("FluentVision.UI.Lang.lang", typeof(LanguageManager).Assembly);
这样不指定CultureInfo的情况下,会使用lang.resx 这个默认资源文件。
3.数据绑定系统
实际上LanguageManager 相当于一个View的一个ViewModel,xaml中使用Binding 绑定了LanguageManager 的属性,然后切换语言的时候,通过PropertyChanged事件实现界面数据刷新,跟平常使用的MVVM思想一致。
索引器是类的有参属性,查看IL发现实际上生成了一个名字是Item的属性:

所以上面代码才会这样写:
cs
// "item[]" 就是指上面的 this[string name] 索引器 名称
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("item[]"));