feat: 完成国际化支持库
This commit is contained in:
19
JackCraft.I18N/Converters/I18NConverter.cs
Normal file
19
JackCraft.I18N/Converters/I18NConverter.cs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
using System.Globalization;
|
||||||
|
using Avalonia.Data.Converters;
|
||||||
|
|
||||||
|
namespace JackCraft.I18N.Converters;
|
||||||
|
|
||||||
|
internal class I18NConverter(I18NBinding binding, object[] bindingValues) : IMultiValueConverter
|
||||||
|
{
|
||||||
|
public object? Convert(IList<object?> values, Type targetType, object? parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
if (values.Count < 2 || values[0] is not CultureInfo)
|
||||||
|
return null;
|
||||||
|
if (binding.KeyConverter.Convert(values[1], null!, null, culture) is not string key)
|
||||||
|
return values[1];
|
||||||
|
var value = I18NConfig.Manager.Get<object>(key, values[0] as CultureInfo);
|
||||||
|
if (value is string str && bindingValues.Length > 0)
|
||||||
|
value = string.Format(str, bindingValues);
|
||||||
|
return binding.ValueConverter.Convert(value, null!, null, culture);
|
||||||
|
}
|
||||||
|
}
|
22
JackCraft.I18N/Converters/I18NKeyConverter.cs
Normal file
22
JackCraft.I18N/Converters/I18NKeyConverter.cs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
using System.Globalization;
|
||||||
|
using Avalonia.Data.Converters;
|
||||||
|
|
||||||
|
namespace JackCraft.I18N.Converters;
|
||||||
|
|
||||||
|
internal class I18NKeyConverter : IValueConverter
|
||||||
|
{
|
||||||
|
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
return value switch
|
||||||
|
{
|
||||||
|
Enum e => value.GetType().Name + "." + e,
|
||||||
|
string str => str,
|
||||||
|
_ => null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
17
JackCraft.I18N/Converters/I18NValueConverter.cs
Normal file
17
JackCraft.I18N/Converters/I18NValueConverter.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
using System.Globalization;
|
||||||
|
using Avalonia.Data.Converters;
|
||||||
|
|
||||||
|
namespace JackCraft.I18N.Converters;
|
||||||
|
|
||||||
|
internal class I18NValueConverter : IValueConverter
|
||||||
|
{
|
||||||
|
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
23
JackCraft.I18N/I18NBinding.cs
Normal file
23
JackCraft.I18N/I18NBinding.cs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
using Avalonia.Data;
|
||||||
|
using Avalonia.Data.Converters;
|
||||||
|
using JackCraft.I18N.Converters;
|
||||||
|
|
||||||
|
namespace JackCraft.I18N;
|
||||||
|
|
||||||
|
internal class I18NBinding : MultiBinding
|
||||||
|
{
|
||||||
|
public readonly IValueConverter KeyConverter;
|
||||||
|
public readonly IValueConverter ValueConverter;
|
||||||
|
|
||||||
|
public I18NBinding(string key, params dynamic[] values)
|
||||||
|
{
|
||||||
|
Mode = BindingMode.OneWay;
|
||||||
|
TargetNullValue = key;
|
||||||
|
FallbackValue = key;
|
||||||
|
Converter = new I18NConverter(this, values);
|
||||||
|
KeyConverter = new I18NKeyConverter();
|
||||||
|
ValueConverter = new I18NValueConverter();
|
||||||
|
Bindings.Add(new Binding { Source = I18NConfig.Manager, Path = nameof(I18NConfig.Manager.Culture) });
|
||||||
|
Bindings.Add(new Binding { Source = key });
|
||||||
|
}
|
||||||
|
}
|
12
JackCraft.I18N/I18NConfig.cs
Normal file
12
JackCraft.I18N/I18NConfig.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using System.Globalization;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace JackCraft.I18N;
|
||||||
|
|
||||||
|
internal static class I18NConfig
|
||||||
|
{
|
||||||
|
public static I18NManager Manager { get; set; } = null!;
|
||||||
|
public static string BaseName { get; set; } = string.Empty;
|
||||||
|
public static Assembly Assembly { get; set; } = typeof(I18NConfig).Assembly;
|
||||||
|
public static CultureInfo Culture { get; set; } = CultureInfo.InvariantCulture;
|
||||||
|
}
|
15
JackCraft.I18N/I18NExtension.cs
Normal file
15
JackCraft.I18N/I18NExtension.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
using Avalonia.Markup.Xaml;
|
||||||
|
|
||||||
|
namespace JackCraft.I18N;
|
||||||
|
|
||||||
|
public class I18NExtension(string key, params object[] values) : MarkupExtension
|
||||||
|
{
|
||||||
|
public I18NExtension(string key) : this(key, [])
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override object ProvideValue(IServiceProvider serviceProvider)
|
||||||
|
{
|
||||||
|
return new I18NBinding(key, values);
|
||||||
|
}
|
||||||
|
}
|
48
JackCraft.I18N/I18NManager.cs
Normal file
48
JackCraft.I18N/I18NManager.cs
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Resources;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
namespace JackCraft.I18N;
|
||||||
|
|
||||||
|
public sealed class I18NManager : INotifyPropertyChanged
|
||||||
|
{
|
||||||
|
public I18NManager(string baseName, Assembly assembly)
|
||||||
|
{
|
||||||
|
I18NConfig.BaseName = baseName;
|
||||||
|
I18NConfig.Assembly = assembly;
|
||||||
|
I18NConfig.Manager = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CultureInfo Culture
|
||||||
|
{
|
||||||
|
get => I18NConfig.Culture;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (Equals(value, I18NConfig.Culture)) return;
|
||||||
|
I18NConfig.Culture = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string BaseName => I18NConfig.BaseName;
|
||||||
|
public static Assembly Assembly => I18NConfig.Assembly;
|
||||||
|
public event PropertyChangedEventHandler? PropertyChanged;
|
||||||
|
|
||||||
|
private void OnPropertyChanged([CallerMemberName] string? propertyName = null)
|
||||||
|
{
|
||||||
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||||
|
}
|
||||||
|
|
||||||
|
public T? Get<T>(string key, CultureInfo? culture = null, params object?[] values)
|
||||||
|
{
|
||||||
|
culture ??= Culture;
|
||||||
|
var resourceManager = new ResourceManager(BaseName, Assembly);
|
||||||
|
var resourceSet = resourceManager.GetResourceSet(culture, true, true);
|
||||||
|
var obj = resourceSet?.GetObject(key);
|
||||||
|
if (obj is string str && values.Length > 0) return (dynamic)string.Format(str, values);
|
||||||
|
if (obj != null) return (dynamic)obj;
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
}
|
@@ -7,4 +7,8 @@
|
|||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Avalonia" Version="11.2.3"/>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
Reference in New Issue
Block a user