# 05 - 国际化(i18n)示例
演示如何使用 Sharp.Wpf 的国际化功能实现多语言支持,包括运行时切换语言、资源文件管理等。
## 🎯 学习目标
- 使用 `ILocalizationService` 实现多语言
- 在 XAML 中使用 `{loc:Localize}` 绑定本地化字符串
- 运行时动态切换语言
- 管理资源文件(.resx)
- 格式化带参数的本地化字符串
## 📦 使用的模块
- **Sharp.Wpf** - ILocalizationService, LocalizeExtension
## 🚀 快速运行
```bash
cd examples/05-Localization
dotnet run
```
## 📝 核心代码讲解
### 1. 创建资源文件
```
Resources/
├── Strings.resx # 默认语言(中文)
├── Strings.en-US.resx # 英文
└── Strings.ja-JP.resx # 日文(可选)
```
**Strings.resx** (中文):
```xml
欢迎使用 Sharp 框架
用户名
密码
登录
欢迎, {0}!
```
**Strings.en-US.resx** (英文):
```xml
Welcome to Sharp Framework
Username
Password
Login
Welcome, {0}!
```
### 2. App.xaml.cs - 注册国际化服务
```csharp
using System.Globalization;
using System.Resources;
using Wpf.Localization;
protected override void OnStartup(StartupEventArgs e)
{
var services = new ServiceCollection();
services.AddSharpWpf();
// 添加国际化支持
var resourceManager = new ResourceManager(
"LocalizationExample.Resources.Strings", // 资源文件的完整命名空间
Assembly.GetExecutingAssembly());
services.AddLocalization(
resourceManager,
new CultureInfo("zh-CN"), // 中文
new CultureInfo("en-US"), // 英文
new CultureInfo("ja-JP") // 日文
);
services.AddViewModel();
var provider = services.BuildServiceProvider();
var mainWindow = provider.GetRequiredService();
mainWindow.Show();
}
```
### 3. MainViewModel.cs - 语言切换
```csharp
using Wpf.Localization;
public class MainViewModel : ViewModelBase
{
private readonly ILocalizationService _localization;
private readonly IDialogService _dialogService;
public ILocalizationService Localization => _localization;
public List AvailableLanguages { get; }
public CultureInfo CurrentLanguage
{
get => _localization.CurrentCulture;
set
{
_localization.ChangeCulture(value);
OnPropertyChanged();
}
}
public ICommand ChangeLanguageCommand { get; }
public ICommand ShowGreetingCommand { get; }
public MainViewModel(
ILocalizationService localization,
IDialogService dialogService)
{
_localization = localization;
_dialogService = dialogService;
AvailableLanguages = localization.GetSupportedCultures().ToList();
// 监听语言变化
_localization.CultureChanged += (s, culture) =>
{
_dialogService.ShowMessage(
$"语言已切换到: {culture.NativeName}",
"提示");
};
ChangeLanguageCommand = new RelayCommand(culture =>
{
if (culture != null)
{
CurrentLanguage = culture;
}
});
ShowGreetingCommand = new RelayCommand(() =>
{
// 使用格式化字符串
var message = _localization.GetString("WelcomeUser", "张三");
_dialogService.ShowMessage(message, "问候");
});
}
}
```
### 4. MainWindow.xaml - 使用本地化绑定
```xml
```
### 5. 在代码中使用本地化
```csharp
// 方式1: 通过服务获取
var welcomeText = _localization.GetString("Welcome");
// 方式2: 带格式化参数
var greeting = _localization.GetString("WelcomeUser", username);
// 方式3: 索引器(用于绑定)
var password = _localization["Password"];
```
## 🎓 练习建议
### 练习1:添加更多语言
添加法语(fr-FR)或德语(de-DE)资源文件。
### 练习2:保存语言偏好
将用户选择的语言保存到配置文件,下次启动时自动加载。
### 练习3:动态加载资源
实现从外部 JSON 文件加载翻译资源(而非编译进程序)。
### 练习4:翻译进度显示
显示每种语言的翻译完成度(如:英文 95%,日文 60%)。
## 💡 常见问题
**Q: 资源文件修改后不生效?**
A: 确保:
1. 资源文件的"生成操作"设为"嵌入的资源"
2. 重新生成项目(Clean + Rebuild)
**Q: 如何支持从右到左(RTL)语言?**
A: 监听 CultureChanged 事件,设置 `FlowDirection`:
```csharp
_localization.CultureChanged += (s, culture) => {
if (culture.TextInfo.IsRightToLeft) {
Application.Current.MainWindow.FlowDirection = FlowDirection.RightToLeft;
}
};
```
**Q: 能否热重载资源文件?**
A: Sharp.Wpf 当前使用编译时嵌入资源,不支持运行时重载。可以使用外部 JSON 文件实现热重载。
**Q: 如何处理复数形式?**
A: 使用不同的资源键或使用占位符:
```
"{Count} items" → "{0} 个项目"
```
## 📚 延伸阅读
- [.NET 资源文件](https://learn.microsoft.com/zh-cn/dotnet/core/extensions/resources)
- [CultureInfo 类](https://learn.microsoft.com/zh-cn/dotnet/api/system.globalization.cultureinfo)
- [WPF 本地化](https://learn.microsoft.com/zh-cn/dotnet/desktop/wpf/advanced/globalization-for-wpf)
- 下一个示例:[06-Theming](../06-Theming/README.md)
---
**构建面向全球用户的应用!** 🌍