在當今全球化的軟件開發(fā)浪潮中,應(yīng)用的國際化(i18n)與本地化(L10n)顯得尤為重要。Avalonia UI 作為一款強大的跨平臺 UI 框架,為開發(fā)者提供了多種實現(xiàn)國際化的途徑。其中,使用傳統(tǒng)的 Resx 資源文件進行國際化處理,不僅兼容了原 Winform、WPF、ASP.NET Core 等開發(fā)場景下的使用習慣,還借助一些實用工具和特定的開發(fā)流程,讓國際化的實現(xiàn)變得高效且有條理。
1. 引言:Resx 資源文件與 Avalonia UI 國際化的邂逅
在軟件開發(fā)領(lǐng)域,國際化是確保應(yīng)用能夠跨越語言和文化邊界,觸達全球用戶的關(guān)鍵。Avalonia UI 以其靈活的架構(gòu)和豐富的功能,在跨平臺應(yīng)用開發(fā)中嶄露頭角。而 Resx 資源文件,作為一種久經(jīng)考驗的本地化資源管理方式,在 Avalonia UI 中也找到了新的用武之地。通過將兩者結(jié)合,開發(fā)者能夠在熟悉的開發(fā)模式下,為應(yīng)用賦予多語言支持的能力,輕松應(yīng)對不同地區(qū)用戶的需求。
下圖是使用VS擴展 ResXManager 對Resx資源文件進行管理的截圖:
2. 詳細使用步驟:構(gòu)建多語言應(yīng)用的基石
2.1. Resx 資源文件的精心布局
2.1.1. 項目目錄規(guī)劃與基礎(chǔ)資源文件創(chuàng)建
開啟您的 Avalonia UI 項目之旅,無論是已有的成熟項目還是全新創(chuàng)建的項目,首先在項目中添加一個用于存放國際化資源的目錄,這里我們命名為 I18n
(您可根據(jù)項目實際情況自定義目錄名)。在這個目錄下,創(chuàng)建默認的英文語言資源文件 Resource.resx
。這個文件將作為整個國際化資源體系的基礎(chǔ),承載著應(yīng)用在英文環(huán)境下的所有文本資源。
2.1.2. 多語言資源文件的拓展
- 當英文資源文件就緒后,我們可以進一步拓展其他語言的資源文件。以中文簡體、中文繁體和日語為例,它們的文件名需要遵循特定的命名規(guī)則:文件名前綴與默認語言資源文件名保持一致,即
Resource
,并添加對應(yīng)的CultureName
后綴。例如,中文簡體對應(yīng)的資源文件名為Resource.zh-CN.resx
,中文繁體為Resource.zh-Hant.resx
,日語則是Resource.ja-JP.resx
。這樣的命名方式有助于 Avalonia UI 在運行時準確識別并加載不同語言的資源。 - 借助強大的 ResXManager 工具,我們可以方便地打開這些資源文件進行多語言文本的編輯。在編輯過程中,需要特別注意語言 Key 的命名,它必須滿足 C# 變量語法,因為后續(xù)的開發(fā)流程會依據(jù)這些 Key 生成對應(yīng)的語言 Key 類,確保在代碼層面能夠精準地引用和操作這些資源。
2.2. NuGet 包的引入:增強國際化功能的得力助手
Install-Package AvaloniaExtensions.Axaml
這個包為我們的項目帶來了一系列實用的 API,包括多語言切換功能、便捷的獲取 Key 對應(yīng)翻譯字符串的方法,以及在 axaml
前端界面中對語言標記的支持。這些功能將極大地簡化我們在國際化開發(fā)過程中的代碼編寫和界面設(shè)計工作。
2.3. T4 文件:從資源文件到強類型資源類的橋梁
2.3.1. T4 文件的創(chuàng)建與配置
有了資源文件后,雖然已經(jīng)能夠在一定程度上實現(xiàn)國際化功能,但直接使用字符串 Key 在代碼中進行資源引用既容易出錯又不夠直觀。因此,我們引入 T4 文件來根據(jù)資源文件生成強類型的資源類。在之前創(chuàng)建的 I18n
目錄下,添加一個 T4 文件,例如 Language.tt
(文件名可根據(jù)項目需求靈活調(diào)整)。
2.3.2. T4 文件的內(nèi)容解析與生成邏輯
打開 Language.tt
文件,其內(nèi)容包含了一系列的指令和代碼片段。首先,通過 #import
指令引入了多個命名空間,這些命名空間為后續(xù)的代碼操作提供了必要的功能支持,如處理 XML 數(shù)據(jù)、文件操作等。
<#@ 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
變量指定了前面創(chuàng)建的默認 Resx 資源文件名,這是 T4 文件生成強類型資源類的依據(jù)。在 T4 文件的主體部分,通過 XElement.Load
方法加載指定的資源文件,并使用 LINQ 查詢表達式從資源文件的 XML 結(jié)構(gòu)中提取出所有的語言 Key。然后,針對每個提取到的 Key,生成一個對應(yīng)的公共靜態(tài)只讀字符串字段,字段名與 Key 相同,初始值也為 Key。這樣,當 T4 文件執(zhí)行保存操作(通常通過 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. 在項目中的具體應(yīng)用:讓多語言功能鮮活起來
2.4.1. 代碼中的資源引用
在 C# 代碼中,我們可以借助 I18nManager
類來獲取指定語言 Key 對應(yīng)的翻譯字符串。例如:
I18nManager.GetString(Language.Setting)
這里的 Language.Setting
就是通過 T4 文件生成的強類型資源類中的字段,通過這種方式,我們能夠在代碼的任何地方方便地獲取并使用多語言資源,確保應(yīng)用在不同語言環(huán)境下的正確顯示。
2.4.2. Axaml 界面中的語言綁定
在 axaml
前端界面中,我們首先需要引入相應(yīng)的命名空間:
xmlns:i18n="https://codewf.com"
xmlns:language="clr-namespace:CodeWF.Toolbox.I18n"
然后,通過數(shù)據(jù)綁定的方式將界面元素的文本屬性與語言資源關(guān)聯(lián)起來。例如:
<TextBlock Text="{i18n:I18n {x:Static language:Language.AppName}}" />
這樣,當應(yīng)用的語言環(huán)境發(fā)生變化時,界面元素的文本會自動更新為對應(yīng)的翻譯文本,實現(xiàn)了界面的動態(tài)國際化。
- 語言切換的實現(xiàn)
實現(xiàn)語言切換功能也非常簡單,只需調(diào)用 I18nManager.Instance.Culture
屬性,并傳入目標語言的 CultureInfo
對象即可。例如:
I18nManager.Instance.Culture = new CultureInfo(language);
這里的 language
變量可以是任何有效的語言代碼,如 zh-CN
、ja-JP
等。當設(shè)置了新的語言文化后,整個應(yīng)用的語言顯示會立即更新,為用戶提供無縫的多語言切換體驗。
3. 總結(jié):Resx 資源文件國際化方案的優(yōu)劣剖析
通過 Resx 資源文件實現(xiàn) Avalonia UI 應(yīng)用的國際化,無疑為傳統(tǒng)開發(fā)者提供了一條熟悉且便捷的道路。它充分利用了已有的開發(fā)經(jīng)驗和工具生態(tài),如 ResXManager 和 T4 文件技術(shù),使得國際化的開發(fā)過程能夠高效地融入到現(xiàn)有的項目流程中。然而,這種方式也并非完美無缺。其對于普通用戶側(cè)的維護來說,可能存在一定的難度。普通用戶可能不熟悉 Resx 文件的結(jié)構(gòu)和編輯方式,也難以理解 T4 文件生成代碼的邏輯。這就要求在項目的設(shè)計和實施過程中,開發(fā)者需要充分考慮到后續(xù)的維護成本,可能需要為普通用戶提供一些簡單易用的界面或工具來輔助他們進行國際化資源的更新和管理。但總體而言,對于具有一定技術(shù)基礎(chǔ)的開發(fā)團隊和項目來說,Resx 資源文件的國際化方案仍然是一種值得推薦的選擇,它在功能、效率和兼容性方面都有著出色的表現(xiàn)。
希望本文能夠為廣大 Avalonia UI 開發(fā)者在國際化實踐中提供有益的參考和指導(dǎo),讓您的應(yīng)用能夠在全球舞臺上綻放光彩。
彩蛋:下篇文章介紹XML文件實現(xiàn)國際化