【WPF】本地化的另一种实现方式——源生成器

1.为什么要重新写一篇

本篇文章仅适用于.NET5及更新版本

在之前的文章中,我们介绍了使用 WPF 实现本地化的方案,主要包括利用官方推荐的静态资源和 XAML 动态资源的方式。然而,我们也意识到这些方法存在一些显著的缺陷:

  1. 静态资源的局限性:静态资源无法在运行时实现语言切换,也无法支持设计界面的实时预览,这给本地化带来了一定的不便。
  2. XAML 动态资源的挑战:虽然使用 XAML 动态资源能够实现实时预览,但由于并非官方推荐的方式,以及资源管理相对复杂,这也给开发者带来了一些困扰。

针对这些问题,我们深入研究并探索了更为优化的解决方案,以应对 WPF 本地化中的挑战。我们期待与您分享更多关于 WPF 本地化最佳实践的内容,并帮助您更好地解决这些挑战。

我们相信最新的文章将为您提供更多深入见解,帮助您克服 WPF 本地化中遇到的问题。
对感兴趣的可以看看【WPF】 本地化的最佳做法

诚然使用源生成器的方式也有一定的局限性,比如 Source Generators 在 .NET 5 中引入的因此在旧的 .NET 平台下不能完美使用。

2.什么是源生成器

如果对源生成器不了解移步⬇️
C# 源生成器

3. 解决方案

解决方案结构

3.1 源生成器创建

  1. 创建单独的 SourceGenerator 项目
  2. 项目配置 PropertyGroup 中添加 <EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
  3. 引用类库:Microsoft.CodeAnalysis 和 Microsoft.CodeAnalysis.CSharp
  4. 创建相关的实现类,实现 IIncrementalGenerator 接口

3.2 实现原理

在 .NET 中,当您使用资源文件(例如 .resx 文件)时,您可以通过资源键来读取相应的值。这是因为 .NET 在编译资源文件时,会为每个资源项(键值对)生成一个静态只读属性,该属性的名称与资源键相对应

这是通过代码生成和部分类的机制实现的。当您在 Visual Studio 中添加资源文件并设置资源键值后,Visual Studio 会在后台自动生成一个同名的部分类,其中包含每个资源键对应的静态只读属性

根据生成的 Resource 类将其中的属性值读取出来

3.3 主程序实现

  1. 引用 SourceGenerator 项目
  2. 项目配置 <ProjectReference Include="..\生成器项目.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="true"/>
  3. 创建 Resources 资源文件,默认为英文资源创建
<TextBlock VerticalAlignment="Center" Text="{Binding Source={x:Static res:ResourceExtension.Instance}, Path=Hello}" />

初始化和保存语言

public void Initialize()
{
    var cultureName = AppSettingManager.Get("language");
    var cultureInfo = new System.Globalization.CultureInfo(cultureName);
    Thread.CurrentThread.CurrentUICulture = cultureInfo;
    Thread.CurrentThread.CurrentCulture = cultureInfo;
}

private void SetCurrentCulture(string cultureName)
{
    AppSettingManager.Set("language", cultureName);
    var cultureInfo = new System.Globalization.CultureInfo(cultureName);
    Thread.CurrentThread.CurrentUICulture = cultureInfo;
    Thread.CurrentThread.CurrentCulture = cultureInfo;
}

用法演示

观看演示视频:多语言本地化一种方式

posted @ 2026-10-05 17:59  JacePan  阅读(6)  评论(0)    收藏  举报