From e25d4639de5824b610ec7ccfca491df5fec34a67 Mon Sep 17 00:00:00 2001
From: Jack <3486688394@qq.com>
Date: Mon, 19 Jan 2026 03:21:26 +0800
Subject: [PATCH] =?UTF-8?q?feat(i18n):=20=E6=94=AF=E6=8C=81=E7=BB=91?=
=?UTF-8?q?=E5=AE=9A=E8=A1=A8=E8=BE=BE=E5=BC=8F=E4=BD=9C=E4=B8=BA=E5=9B=BD?=
=?UTF-8?q?=E9=99=85=E5=8C=96=E9=94=AE=E5=80=BC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 将 I18NBinding 构造函数的 key 参数从 string 类型改为 object 类型
- 添加对 BindingBase 类型键值的支持,允许动态绑定国际化键
- 为 I18NExtension 添加多个构造函数重载以支持 BindingBase 键值
- 更新资源文件添加新的测试键值对
- 修改视图模型属性访问修饰符并添加测试属性
- 在主窗口视图中添加绑定表达式的国际化使用示例
---
JackCraft.I18N/I18NBinding.cs | 23 +++++++---
JackCraft.I18N/I18NExtension.cs | 49 +++++++++++++++++++++-
TestMvvm/Assets/Resources.resx | 6 ++-
TestMvvm/Assets/Resources.zh-hans.resx | 3 ++
TestMvvm/ViewModels/MainWindowViewModel.cs | 3 +-
TestMvvm/Views/MainWindow.axaml | 1 +
6 files changed, 76 insertions(+), 9 deletions(-)
diff --git a/JackCraft.I18N/I18NBinding.cs b/JackCraft.I18N/I18NBinding.cs
index 1adaad0..61a8dc6 100644
--- a/JackCraft.I18N/I18NBinding.cs
+++ b/JackCraft.I18N/I18NBinding.cs
@@ -9,7 +9,7 @@ internal class I18NBinding : MultiBinding
public readonly IValueConverter KeyConverter;
public readonly IValueConverter ValueConverter;
- public I18NBinding(string key, params dynamic[] values)
+ public I18NBinding(object key, params dynamic[] values)
{
Mode = BindingMode.OneWay;
TargetNullValue = key;
@@ -18,13 +18,26 @@ internal class I18NBinding : MultiBinding
KeyConverter = new I18NKeyConverter();
ValueConverter = new I18NValueConverter();
Bindings.Add(new Binding { Source = I18NConfig.Manager, Path = nameof(I18NConfig.Manager.Culture) });
- Bindings.Add(new Binding { Source = key });
- foreach (var value in values)
+
+ switch (key)
{
- if (value is BindingBase binding)
+ // 处理 key 参数,可能是字符串或 BindingBase
+ case string keyStr:
+ Bindings.Add(new Binding { Source = keyStr });
+ break;
+ case BindingBase binding:
Bindings.Add(binding);
+ break;
+ // 其他情况,作为普通对象处理
+ default:
+ Bindings.Add(new Binding { Source = key });
+ break;
+ }
+
+ foreach (var value in values)
+ if (value is BindingBase valueBinding)
+ Bindings.Add(valueBinding);
else
Bindings.Add(new Binding { Source = value });
- }
}
}
\ No newline at end of file
diff --git a/JackCraft.I18N/I18NExtension.cs b/JackCraft.I18N/I18NExtension.cs
index 5a4a8be..862e9f9 100644
--- a/JackCraft.I18N/I18NExtension.cs
+++ b/JackCraft.I18N/I18NExtension.cs
@@ -1,9 +1,19 @@
+using Avalonia.Data;
using Avalonia.Markup.Xaml;
namespace JackCraft.I18N;
-public class I18NExtension(string key, params dynamic[] values) : MarkupExtension
+public class I18NExtension : MarkupExtension
{
+ private readonly object _key;
+ private readonly dynamic[] _values;
+
+ public I18NExtension(string key, params dynamic[] values)
+ {
+ _key = key;
+ _values = values;
+ }
+
public I18NExtension(string key) : this(key, [])
{
}
@@ -31,8 +41,43 @@ public class I18NExtension(string key, params dynamic[] values) : MarkupExtensio
{
}
+ // 支持 BindingBase 作为 key
+ public I18NExtension(BindingBase key, params dynamic[] values)
+ {
+ _key = key;
+ _values = values;
+ }
+
+ public I18NExtension(BindingBase key) : this(key, [])
+ {
+ }
+
+ public I18NExtension(BindingBase key, dynamic value1) : this(key, [value1])
+ {
+ }
+
+ public I18NExtension(BindingBase key, dynamic value1, dynamic value2) : this(key, [value1, value2])
+ {
+ }
+
+ public I18NExtension(BindingBase key, dynamic value1, dynamic value2, dynamic value3) : this(key,
+ [value1, value2, value3])
+ {
+ }
+
+ public I18NExtension(BindingBase key, dynamic value1, dynamic value2, dynamic value3, dynamic value4) : this(key,
+ [value1, value2, value3, value4])
+ {
+ }
+
+ public I18NExtension(BindingBase key, dynamic value1, dynamic value2, dynamic value3, dynamic value4,
+ dynamic value5) :
+ this(key, [value1, value2, value3, value4, value5])
+ {
+ }
+
public override object ProvideValue(IServiceProvider serviceProvider)
{
- return new I18NBinding(key, values);
+ return new I18NBinding(_key, _values);
}
}
\ No newline at end of file
diff --git a/TestMvvm/Assets/Resources.resx b/TestMvvm/Assets/Resources.resx
index 53651eb..ee65c91 100644
--- a/TestMvvm/Assets/Resources.resx
+++ b/TestMvvm/Assets/Resources.resx
@@ -1,7 +1,8 @@
-
@@ -26,4 +27,7 @@
Test1: {0}
+
+ Test2Test2
+
\ No newline at end of file
diff --git a/TestMvvm/Assets/Resources.zh-hans.resx b/TestMvvm/Assets/Resources.zh-hans.resx
index bbdc8f4..ee63f84 100644
--- a/TestMvvm/Assets/Resources.zh-hans.resx
+++ b/TestMvvm/Assets/Resources.zh-hans.resx
@@ -18,4 +18,7 @@
测试1: {0}
+
+ 测试2测试2
+
\ No newline at end of file
diff --git a/TestMvvm/ViewModels/MainWindowViewModel.cs b/TestMvvm/ViewModels/MainWindowViewModel.cs
index 082a5f9..4efc7ab 100644
--- a/TestMvvm/ViewModels/MainWindowViewModel.cs
+++ b/TestMvvm/ViewModels/MainWindowViewModel.cs
@@ -7,7 +7,8 @@ namespace TestMvvm.ViewModels;
public partial class MainWindowViewModel : ViewModelBase
{
- [ObservableProperty] public string? test = Path.GetRandomFileName();
+ [ObservableProperty] private string? _test = Path.GetRandomFileName();
+ [ObservableProperty] private string _test2 = "Test2";
[RelayCommand]
public void RandomText()
diff --git a/TestMvvm/Views/MainWindow.axaml b/TestMvvm/Views/MainWindow.axaml
index c249cbb..7bb8d9e 100644
--- a/TestMvvm/Views/MainWindow.axaml
+++ b/TestMvvm/Views/MainWindow.axaml
@@ -19,6 +19,7 @@
+