Avalonia 国际化之路:Resx 资源文件的深度应用与探索

news/2024/12/20 9:17:37/文章来源:https://www.cnblogs.com/Dotnet9-com/p/18618351

在当今全球化的软件开发浪潮中,应用的国际化(i18n)与本地化(L10n)显得尤为重要。Avalonia UI 作为一款强大的跨平台 UI 框架,为开发者提供了多种实现国际化的途径。其中,使用传统的 Resx 资源文件进行国际化处理,不仅兼容了原 Winform、WPF、ASP.NET Core 等开发场景下的使用习惯,还借助一些实用工具和特定的开发流程,让国际化的实现变得高效且有条理。

1. 引言:Resx 资源文件与 Avalonia UI 国际化的邂逅

在软件开发领域,国际化是确保应用能够跨越语言和文化边界,触达全球用户的关键。Avalonia UI 以其灵活的架构和丰富的功能,在跨平台应用开发中崭露头角。而 Resx 资源文件,作为一种久经考验的本地化资源管理方式,在 Avalonia UI 中也找到了新的用武之地。通过将两者结合,开发者能够在熟悉的开发模式下,为应用赋予多语言支持的能力,轻松应对不同地区用户的需求。

下图是使用VS扩展 ResXManager 对Resx资源文件进行管理的截图:

2. 详细使用步骤:构建多语言应用的基石

2.1. Resx 资源文件的精心布局

2.1.1. 项目目录规划与基础资源文件创建

开启您的 Avalonia UI 项目之旅,无论是已有的成熟项目还是全新创建的项目,首先在项目中添加一个用于存放国际化资源的目录,这里我们命名为 I18n(您可根据项目实际情况自定义目录名)。在这个目录下,创建默认的英文语言资源文件 Resource.resx。这个文件将作为整个国际化资源体系的基础,承载着应用在英文环境下的所有文本资源。

2.1.2. 多语言资源文件的拓展

  • 当英文资源文件就绪后,我们可以进一步拓展其他语言的资源文件。以中文简体、中文繁体和日语为例,它们的文件名需要遵循特定的命名规则:文件名前缀与默认语言资源文件名保持一致,即 Resource,并添加对应的 CultureName 后缀。例如,中文简体对应的资源文件名为 Resource.zh-CN.resx,中文繁体为 Resource.zh-Hant.resx,日语则是 Resource.ja-JP.resx。这样的命名方式有助于 Avalonia UI 在运行时准确识别并加载不同语言的资源。
  • 借助强大的 ResXManager 工具,我们可以方便地打开这些资源文件进行多语言文本的编辑。在编辑过程中,需要特别注意语言 Key 的命名,它必须满足 C# 变量语法,因为后续的开发流程会依据这些 Key 生成对应的语言 Key 类,确保在代码层面能够精准地引用和操作这些资源。

2.2. NuGet 包的引入:增强国际化功能的得力助手

Install-Package AvaloniaExtensions.Axaml

这个包为我们的项目带来了一系列实用的 API,包括多语言切换功能、便捷的获取 Key 对应翻译字符串的方法,以及在 axaml 前端界面中对语言标记的支持。这些功能将极大地简化我们在国际化开发过程中的代码编写和界面设计工作。

2.3. T4 文件:从资源文件到强类型资源类的桥梁

2.3.1. T4 文件的创建与配置

有了资源文件后,虽然已经能够在一定程度上实现国际化功能,但直接使用字符串 Key 在代码中进行资源引用既容易出错又不够直观。因此,我们引入 T4 文件来根据资源文件生成强类型的资源类。在之前创建的 I18n 目录下,添加一个 T4 文件,例如 Language.tt(文件名可根据项目需求灵活调整)。

2.3.2. T4 文件的内容解析与生成逻辑

打开 Language.tt 文件,其内容包含了一系列的指令和代码片段。首先,通过 #import 指令引入了多个命名空间,这些命名空间为后续的代码操作提供了必要的功能支持,如处理 XML 数据、文件操作等。


<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="System.Xml" #>
<#@ assembly name="System.Xml.Linq" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Xml.Linq" #>
<#@ import namespace="System.IO" #>
<#@ output extension=".cs" #>
//------------------------------------------------------------------------------  
// <auto-generated>  
//     This code was generated by a tool.  
//     Changes to this file may cause incorrect behavior and will be lost if  
//     the code is regenerated.  
// </auto-generated>  
//------------------------------------------------------------------------------
<#const string ResourceFileName = "Resources.resx";
#>namespace <#=System.Runtime.Remoting.Messaging.CallContext.LogicalGetData("NamespaceHint").ToString()#>;public static class Language
{
<#var resourceKeys = XElement.Load(this.Host.ResolvePath(ResourceFileName)).Elements("data").Select(item => item.Attribute("name")?.Value).Where(item => item != null);var resourceDesignerName = Path.GetFileNameWithoutExtension(ResourceFileName);foreach (string resourceKey in resourceKeys){
#>public static readonly string <#= resourceKey #> = "<#= resourceKey #>";
<#}
#>
}

其中,ResourceFileName 变量指定了前面创建的默认 Resx 资源文件名,这是 T4 文件生成强类型资源类的依据。在 T4 文件的主体部分,通过 XElement.Load 方法加载指定的资源文件,并使用 LINQ 查询表达式从资源文件的 XML 结构中提取出所有的语言 Key。然后,针对每个提取到的 Key,生成一个对应的公共静态只读字符串字段,字段名与 Key 相同,初始值也为 Key。这样,当 T4 文件执行保存操作(通常通过 Ctrl + S)时,就会在相同目录下生成一个名为 Language.cs 的 C# 文件,其中包含了强类型的资源类。例如:


//------------------------------------------------------------------------------  
// <auto-generated>  
//     This code was generated by a tool.  
//     Changes to this file may cause incorrect behavior and will be lost if  
//     the code is regenerated.  
// </auto-generated>  
//------------------------------------------------------------------------------namespace CodeWF.Toolbox.I18n;public static class Language
{public static readonly string AppName = "AppName";public static readonly string Home = "Home";public static readonly string SearchToolTip = "SearchToolTip";public static readonly string Setting = "Setting";public static readonly string DesiredAvailabilityNotification = "DesiredAvailabilityNotification";public static readonly string AccessToolbox = "AccessToolbox";public static readonly string MissingTool = "MissingTool";public static readonly string InterfaceStyleSettings = "InterfaceStyleSettings";public static readonly string GeneralSettings = "GeneralSettings";public static readonly string Theme = "Theme";public static readonly string FollowingSystem = "FollowingSystem";public static readonly string LightMode = "LightMode";public static readonly string DarkMode = "DarkMode";public static readonly string LanguageKey = "LanguageKey";public static readonly string AutoOpenToolboxAtStartup = "AutoOpenToolboxAtStartup";public static readonly string HideTrayIconOnClose = "HideTrayIconOnClose";public static readonly string TurnOn = "TurnOn";public static readonly string TurnOff = "TurnOff";public static readonly string Exit = "Exit";public static readonly string SureExit = "SureExit";public static readonly string FindInTrayIcon = "FindInTrayIcon";public static readonly string ShowMainWindow = "ShowMainWindow";public static readonly string DisplayPromptWhenClosing = "DisplayPromptWhenClosing";public static readonly string NoMorePrompts = "NoMorePrompts";public static readonly string About = "About";public static readonly string AboutMessage = "AboutMessage";
}

这个生成的资源类使得我们在代码中能够以强类型的方式引用资源 Key,大大提高了代码的可读性和可维护性。

2.4. 在项目中的具体应用:让多语言功能鲜活起来

2.4.1. 代码中的资源引用

在 C# 代码中,我们可以借助 I18nManager 类来获取指定语言 Key 对应的翻译字符串。例如:

I18nManager.GetString(Language.Setting)

这里的 Language.Setting 就是通过 T4 文件生成的强类型资源类中的字段,通过这种方式,我们能够在代码的任何地方方便地获取并使用多语言资源,确保应用在不同语言环境下的正确显示。

2.4.2. Axaml 界面中的语言绑定

axaml 前端界面中,我们首先需要引入相应的命名空间:

xmlns:i18n="https://codewf.com"
xmlns:language="clr-namespace:CodeWF.Toolbox.I18n"

然后,通过数据绑定的方式将界面元素的文本属性与语言资源关联起来。例如:

<TextBlock Text="{i18n:I18n {x:Static language:Language.AppName}}" />

这样,当应用的语言环境发生变化时,界面元素的文本会自动更新为对应的翻译文本,实现了界面的动态国际化。

  1. 语言切换的实现

实现语言切换功能也非常简单,只需调用 I18nManager.Instance.Culture 属性,并传入目标语言的 CultureInfo 对象即可。例如:

I18nManager.Instance.Culture = new CultureInfo(language);

这里的 language 变量可以是任何有效的语言代码,如 zh-CNja-JP 等。当设置了新的语言文化后,整个应用的语言显示会立即更新,为用户提供无缝的多语言切换体验。

3. 总结:Resx 资源文件国际化方案的优劣剖析

通过 Resx 资源文件实现 Avalonia UI 应用的国际化,无疑为传统开发者提供了一条熟悉且便捷的道路。它充分利用了已有的开发经验和工具生态,如 ResXManager 和 T4 文件技术,使得国际化的开发过程能够高效地融入到现有的项目流程中。然而,这种方式也并非完美无缺。其对于普通用户侧的维护来说,可能存在一定的难度。普通用户可能不熟悉 Resx 文件的结构和编辑方式,也难以理解 T4 文件生成代码的逻辑。这就要求在项目的设计和实施过程中,开发者需要充分考虑到后续的维护成本,可能需要为普通用户提供一些简单易用的界面或工具来辅助他们进行国际化资源的更新和管理。但总体而言,对于具有一定技术基础的开发团队和项目来说,Resx 资源文件的国际化方案仍然是一种值得推荐的选择,它在功能、效率和兼容性方面都有着出色的表现。

  • AvaloniaExtensions.Axaml
  • Avalonia Resx资源文件实现国际化Sample

希望本文能够为广大 Avalonia UI 开发者在国际化实践中提供有益的参考和指导,让您的应用能够在全球舞台上绽放光彩。

彩蛋:下篇文章介绍XML文件实现国际化

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/855714.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

茶饮门店管理新篇章:板栗看板的实践与启示

茶饮企业可以通过板栗看板实现门店管理的优化和效率提升。从创建团队与看板、设置任务与分配、团队协作与沟通、进度跟踪与数据分析到优化与改进以及安全性能保障等方面入手,全面提升门店管理的水平和效率。近期,库迪咖啡以一种创新的“嵌入式”模式迅速扩展,其门店纷纷入驻…

修改网站首页排序,网站首页内容排序方法

修改网站首页内容的排序通常涉及以下几个步骤:登录后台:使用管理员账号登录网站后台。 找到内容管理:在后台导航中找到“内容管理”或“文章管理”。 编辑内容:选择需要排序的内容,点击“编辑”按钮。 设置排序:在编辑页面中,找到排序选项,设置内容的顺序。常见的排序方…

错误码:NET::ERR_CERT_AUTHORITY_INVALID,解决浏览器提示证书无效的问题

当您在访问某个网站时遇到“NET::ERR_CERT_AUTHORITY_INVALID”错误时,这意味着浏览器认为该网站的SSL证书不是由受信任的证书颁发机构(CA)签发的。这可能是由于多种原因造成的,包括证书过期、自签名证书、中间证书缺失等。以下是一些解决方法:检查证书颁发机构:确认证书…

PbootCMS在阿里云主机上邮件发送失败,提示“服务器已经禁用stream_socket_client和fsockopen函数”,如何解决?

当你在阿里云主机上使用PbootCMS时,如果遇到邮件发送失败,并且提示“服务器已经禁用stream_socket_client和fsockopen函数,请至少开启一个才能发送邮件!”的错误,这通常是因为阿里云主机的安全策略禁用了这些函数。以下是详细的解决步骤:登录阿里云管理后台:打开浏览器,…

高效与安全并重:高科技企业如何借助跨网文件交换系统实现双赢!

高科技企业在运营和发展过程中,会积累大量重要的核心数据,这些数据对于企业的技术创新、市场竞争优势以及商业机密保护至关重要。为了保障自身的信息安全、保护知识产权和核心数字资产,高科技企业通常会通过防火墙、网闸、虚拟化等方式,实施企业内网和外网隔离。实施网络隔…

南通知识付费分销系统搭建

图源 www.tuzhi.ltd在当前的教育和软件领域,知识付费模式正在逐渐普及,成为教育和培训行业的重要趋势之一。尤其在数字化转型的大潮中,在线教育系统的作用日益凸显,其为教学者和学习者之间的知识交流搭建了桥梁。以南通为例,当地的教育机构、老师甚至企业都纷纷尝试采用更…

使用STM32定时器输入捕获的一些记录

(最近在学习六步换相驱动直流无刷电机,记录一下其中陌生的定时器功能) 英文标识含义TIx:通道CHx的外部输入信号;霍尔传感器接口 霍尔传感器接口大概功能逻辑:将CH1~3的输入连接到异或器,输出TI1,实现同时对三个信号的边沿检测; TI1经过滤波、边沿检测 -> TI1F_ED信…

AI应用实战课学习总结(2)hello sk-learn

本文快速搭建了Python机器学习的开发环境,并通过一个简单的降维示例学习了scikit-learn的基本用法,完成了一个hello world程序。大家好,我是Edison。 最近入坑黄佳老师的《AI应用实战课》,记录下我的学习之旅,也算是总结回顾。 今天是我们的第2站,了解下scikit-learn框架…

好消息,在 Visual Studio 中可以免费使用 GitHub Copilot 了!

前言 今天大姚给大家分享一个好消息,GitHub Copilot 可以免费使用了!在此之前若开发者要使用 GitHub Copilot 需要付费订阅,每月订阅费用起步价为 10 美元,而经过验证的学生、教师和开源项目维护者则可以申请免费使用。今天咱们一起来看看在 Visual Studio 使用 GitHub Cop…

读图数据库实战笔记08遍历与子图

遍历与子图1. 使用熟路构建遍历 1.1. 为了避免把开发遍历和构建应用程序混淆1.1.1. 把遍历的编写和测试与应用程序的开发拆分成了两个独立的操作1.1.2. 在Java代码之外独立开发遍历,然后把它们加入应用程序中1.1.3. 现实情况是,大多数开发人员会同时完成两者,不管使用的是哪…

使用css实现圆形的头像的效果(注:要考虑正方形、长方形情况)

在前端开发中,我们经常需要将用户的头像显示为圆形。这可以通过CSS的 border-radius 属性来实现,该属性允许你设置元素的圆角。当 border-radius 设置为 50% 时,无论图片是正方形还是长方形,都会得到一个圆形的效果。但需要注意,长方形图片被裁剪为圆形时,会显示为椭圆形…

任意尺度图像超分辨率的基准技术分析

任意尺度图像超分辨率的基准技术分析 在计算机视觉领域,超分辨率(SR)一直是一个突出的研究领域。它的目的是从低分辨率(LR)图像重建高分辨率(HR)图像。最近,主要基于学习图像的连续表示的任意尺度图像SR取得了重大进展。 这些方法通常需要在特定范围内(即1.0-4.0)使用…