diff --git a/src/Ursa.Themes.Semi/Index.axaml.cs b/src/Ursa.Themes.Semi/Index.axaml.cs
index 21121165..efa20383 100644
--- a/src/Ursa.Themes.Semi/Index.axaml.cs
+++ b/src/Ursa.Themes.Semi/Index.axaml.cs
@@ -1,4 +1,5 @@
using System.Globalization;
+using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Avalonia.Styling;
@@ -7,32 +8,30 @@
namespace Ursa.Themes.Semi;
///
-/// Notice: Don't set Locale if your app is in InvariantGlobalization mode.
+/// Notice: Don't set Locale if your app is in InvariantGlobalization mode.
///
-public class SemiTheme: Styles
+public class SemiTheme : Styles
{
- public static ThemeVariant Aquatic => new ThemeVariant(nameof(Aquatic), ThemeVariant.Dark);
- public static ThemeVariant Desert => new ThemeVariant(nameof(Desert), ThemeVariant.Light);
- public static ThemeVariant Dusk => new ThemeVariant(nameof(Dusk), ThemeVariant.Dark);
- public static ThemeVariant NightSky => new ThemeVariant(nameof(NightSky), ThemeVariant.Dark);
-
- private static readonly Lazy> _localeToResource = new Lazy>(
- () => new Dictionary
- {
- { new CultureInfo("zh-CN"), new zh_cn() },
- { new CultureInfo("en-US"), new en_us() },
- });
-
+ private static readonly Dictionary _localeToResource = new()
+ {
+ { new CultureInfo("zh-CN"), new zh_cn() },
+ { new CultureInfo("en-US"), new en_us() }
+ };
+
private static readonly ResourceDictionary _defaultResource = new zh_cn();
-
- private readonly IServiceProvider? _sp;
+
+ private CultureInfo? _locale;
+
public SemiTheme(IServiceProvider? provider = null)
{
- _sp = provider;
AvaloniaXamlLoader.Load(provider, this);
}
- private CultureInfo? _locale;
+ public static ThemeVariant Aquatic => new(nameof(Aquatic), ThemeVariant.Dark);
+ public static ThemeVariant Desert => new(nameof(Desert), ThemeVariant.Light);
+ public static ThemeVariant Dusk => new(nameof(Dusk), ThemeVariant.Dark);
+ public static ThemeVariant NightSky => new(nameof(NightSky), ThemeVariant.Dark);
+
public CultureInfo? Locale
{
get => _locale;
@@ -40,36 +39,59 @@ public CultureInfo? Locale
{
try
{
- _locale = value;
- var resource = TryGetLocaleResource(value);
- if (resource is null) return;
- foreach (var kv in resource)
+ if (TryGetLocaleResource(value, out var resource) && resource is not null)
+ {
+ _locale = value;
+ foreach (var kv in resource) Resources[kv.Key] = kv.Value;
+ }
+ else
{
- this.Resources.Add(kv);
+ _locale = new CultureInfo("zh-CN");
+ foreach (var kv in _defaultResource) Resources[kv.Key] = kv.Value;
}
}
catch
{
_locale = CultureInfo.InvariantCulture;
}
-
}
}
-
- private static ResourceDictionary? TryGetLocaleResource(CultureInfo? locale)
+
+ private static bool TryGetLocaleResource(CultureInfo? locale, out ResourceDictionary? resourceDictionary)
{
if (Equals(locale, CultureInfo.InvariantCulture))
{
- return _defaultResource;
+ resourceDictionary = _defaultResource;
+ return true;
}
+
if (locale is null)
{
- return _localeToResource.Value[new CultureInfo("zh-CN")];
+ resourceDictionary = _defaultResource;
+ return false;
}
- if (_localeToResource.Value.TryGetValue(locale, out var resource))
+
+ if (_localeToResource.TryGetValue(locale, out var resource))
{
- return resource;
+ resourceDictionary = resource;
+ return true;
}
- return _localeToResource.Value[new CultureInfo("zh-CN")];
+
+ resourceDictionary = _defaultResource;
+ return false;
+ }
+
+ public static void OverrideLocaleResources(Application application, CultureInfo? culture)
+ {
+ if (culture is null) return;
+ if (!_localeToResource.TryGetValue(culture, out var resources)) return;
+ foreach (var kv in resources) application.Resources[kv.Key] = kv.Value;
+ }
+
+ public static void OverrideLocaleResources(StyledElement element, CultureInfo? culture)
+ {
+ if (culture is null) return;
+ if (!_localeToResource.TryGetValue(culture, out var resources)) return;
+ foreach (var kv in resources) element.Resources[kv.Key] = kv.Value;
}
}
\ No newline at end of file
diff --git a/tests/HeadlessTest.Ursa/Semi/LocalizationTest.cs b/tests/HeadlessTest.Ursa/Semi/LocalizationTest.cs
new file mode 100644
index 00000000..fdc3040a
--- /dev/null
+++ b/tests/HeadlessTest.Ursa/Semi/LocalizationTest.cs
@@ -0,0 +1,101 @@
+using System.Globalization;
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Headless.XUnit;
+using Avalonia.Threading;
+using Avalonia.VisualTree;
+using Semi.Avalonia.Locale;
+using Ursa.Controls;
+using Ursa.Themes.Semi;
+
+namespace HeadlessTest.Ursa.Semi;
+
+public class LocalizationTest
+{
+ [AvaloniaFact]
+ public void Default_Locale_Is_Chinese()
+ {
+ var window = new UrsaWindow();
+ window.Show();
+ MessageBox.ShowOverlayAsync("Hello World", button: MessageBoxButton.YesNo, toplevelHashCode: window.GetHashCode());
+ Task.Delay(100).Wait();
+ Dispatcher.UIThread.RunJobs();
+ var dialog = window.GetVisualDescendants().OfType().SingleOrDefault();
+ var yesButton = dialog?.GetVisualDescendants().OfType