From c0277a7004d6afe0888b114ef3c604cb74b02f03 Mon Sep 17 00:00:00 2001 From: Zhang Dian <54255897+zdpcdt@users.noreply.github.com> Date: Thu, 16 Oct 2025 15:12:19 +0800 Subject: [PATCH 1/2] feat: using ResourceDictionary.SetItems to improve Locale switching. --- .../Views/MainView.axaml.cs | 32 ++++---- src/Semi.Avalonia/SemiTheme.axaml.cs | 78 +++++++++---------- 2 files changed, 51 insertions(+), 59 deletions(-) diff --git a/demo/Semi.Avalonia.Demo/Views/MainView.axaml.cs b/demo/Semi.Avalonia.Demo/Views/MainView.axaml.cs index fbc876b..418830b 100644 --- a/demo/Semi.Avalonia.Demo/Views/MainView.axaml.cs +++ b/demo/Semi.Avalonia.Demo/Views/MainView.axaml.cs @@ -90,97 +90,97 @@ public partial class MainViewModel : ObservableObject { Header = "简体中文", Command = SelectLocaleCommand, - CommandParameter = new CultureInfo("zh-cn") + CommandParameter = new CultureInfo("zh-CN") }, new MenuItemViewModel { Header = "English", Command = SelectLocaleCommand, - CommandParameter = new CultureInfo("en-us") + CommandParameter = new CultureInfo("en-US") }, new MenuItemViewModel { Header = "日本語", Command = SelectLocaleCommand, - CommandParameter = new CultureInfo("ja-jp") + CommandParameter = new CultureInfo("ja-JP") }, new MenuItemViewModel { Header = "한국어", Command = SelectLocaleCommand, - CommandParameter = new CultureInfo("ko-kr") + CommandParameter = new CultureInfo("ko-KR") }, new MenuItemViewModel { Header = "English (UK)", Command = SelectLocaleCommand, - CommandParameter = new CultureInfo("en-gb") + CommandParameter = new CultureInfo("en-GB") }, new MenuItemViewModel { Header = "Italiano", Command = SelectLocaleCommand, - CommandParameter = new CultureInfo("it-it") + CommandParameter = new CultureInfo("it-IT") }, new MenuItemViewModel { Header = "Italiano (Switzerland)", Command = SelectLocaleCommand, - CommandParameter = new CultureInfo("it-ch") + CommandParameter = new CultureInfo("it-CH") }, new MenuItemViewModel { Header = "Nederlands", Command = SelectLocaleCommand, - CommandParameter = new CultureInfo("nl-nl") + CommandParameter = new CultureInfo("nl-NL") }, new MenuItemViewModel { Header = "Nederlands (Belgium)", Command = SelectLocaleCommand, - CommandParameter = new CultureInfo("nl-be") + CommandParameter = new CultureInfo("nl-BE") }, new MenuItemViewModel { Header = "Українська", Command = SelectLocaleCommand, - CommandParameter = new CultureInfo("uk-ua") + CommandParameter = new CultureInfo("uk-UA") }, new MenuItemViewModel { Header = "Русский", Command = SelectLocaleCommand, - CommandParameter = new CultureInfo("ru-ru") + CommandParameter = new CultureInfo("ru-RU") }, new MenuItemViewModel { Header = "繁體中文", Command = SelectLocaleCommand, - CommandParameter = new CultureInfo("zh-tw") + CommandParameter = new CultureInfo("zh-TW") }, new MenuItemViewModel { Header = "Deutsch", Command = SelectLocaleCommand, - CommandParameter = new CultureInfo("de-de") + CommandParameter = new CultureInfo("de-DE") }, new MenuItemViewModel { Header = "Español", Command = SelectLocaleCommand, - CommandParameter = new CultureInfo("es-es") + CommandParameter = new CultureInfo("es-ES") }, new MenuItemViewModel { Header = "Polski", Command = SelectLocaleCommand, - CommandParameter = new CultureInfo("pl-pl") + CommandParameter = new CultureInfo("pl-PL") }, new MenuItemViewModel { Header = "Français", Command = SelectLocaleCommand, - CommandParameter = new CultureInfo("fr-fr") + CommandParameter = new CultureInfo("fr-FR") }, ] } diff --git a/src/Semi.Avalonia/SemiTheme.axaml.cs b/src/Semi.Avalonia/SemiTheme.axaml.cs index b9685a7..86cacb8 100644 --- a/src/Semi.Avalonia/SemiTheme.axaml.cs +++ b/src/Semi.Avalonia/SemiTheme.axaml.cs @@ -1,9 +1,7 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Globalization; using Avalonia; using Avalonia.Controls; -using Avalonia.Markup.Xaml; using Avalonia.Styling; using Semi.Avalonia.Locale; @@ -11,35 +9,35 @@ namespace Semi.Avalonia; public class SemiTheme : Styles { - private static readonly Dictionary _localeToResource = new() - { - { new CultureInfo("zh-cn"), new zh_cn() }, - { new CultureInfo("en-us"), new en_us() }, - { new CultureInfo("en-gb"), new en_gb() }, - { new CultureInfo("it-it"), new it_it() }, - { new CultureInfo("it-ch"), new it_ch() }, - { new CultureInfo("nl-be"), new nl_be() }, - { new CultureInfo("nl-nl"), new nl_nl() }, - { new CultureInfo("ja-jp"), new ja_jp() }, - { new CultureInfo("ko-kr"), new ko_kr() }, - { new CultureInfo("uk-ua"), new uk_ua() }, - { new CultureInfo("ru-ru"), new ru_ru() }, - { new CultureInfo("zh-tw"), new zh_tw() }, - { new CultureInfo("de-de"), new de_de() }, - { new CultureInfo("es-es"), new es_es() }, - { new CultureInfo("pl-pl"), new pl_pl() }, - { new CultureInfo("fr-fr"), new fr_fr() }, - }; - - private static readonly ResourceDictionary _defaultResource = new zh_cn(); - - 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); + private static readonly Dictionary LocaleToResource = new() + { + { new CultureInfo("zh-CN"), new zh_cn() }, + { new CultureInfo("en-US"), new en_us() }, + { new CultureInfo("en-GB"), new en_gb() }, + { new CultureInfo("it-IT"), new it_it() }, + { new CultureInfo("it-CH"), new it_ch() }, + { new CultureInfo("nl-BE"), new nl_be() }, + { new CultureInfo("nl-NL"), new nl_nl() }, + { new CultureInfo("ja-JP"), new ja_jp() }, + { new CultureInfo("ko-KR"), new ko_kr() }, + { new CultureInfo("uk-UA"), new uk_ua() }, + { new CultureInfo("ru-RU"), new ru_ru() }, + { new CultureInfo("zh-TW"), new zh_tw() }, + { new CultureInfo("de-DE"), new de_de() }, + { new CultureInfo("es-ES"), new es_es() }, + { new CultureInfo("pl-PL"), new pl_pl() }, + { new CultureInfo("fr-FR"), new fr_fr() }, + }; + + private static readonly ResourceDictionary DefaultResource = new zh_cn(); + + private CultureInfo? _locale; + public CultureInfo? Locale { get => _locale; @@ -50,12 +48,12 @@ public class SemiTheme : Styles if (TryGetLocaleResource(value, out var resource) && resource is not null) { _locale = value; - foreach (var kv in resource) Resources[kv.Key] = kv.Value; + (Resources as ResourceDictionary)?.SetItems(resource); } else { _locale = new CultureInfo("zh-CN"); - foreach (var kv in _defaultResource) Resources[kv.Key] = kv.Value; + (Resources as ResourceDictionary)?.SetItems(DefaultResource); } } catch @@ -69,43 +67,37 @@ public class SemiTheme : Styles { if (Equals(locale, CultureInfo.InvariantCulture)) { - resourceDictionary = _defaultResource; + resourceDictionary = DefaultResource; return true; } if (locale is null) { - resourceDictionary = _defaultResource; + resourceDictionary = DefaultResource; return false; } - if (_localeToResource.TryGetValue(locale, out var resource)) + if (LocaleToResource.TryGetValue(locale, out var resource)) { resourceDictionary = resource; return true; } - resourceDictionary = _defaultResource; + 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; - } + if (!LocaleToResource.TryGetValue(culture, out var resources)) return; + (application.Resources as ResourceDictionary)?.SetItems(resources); } 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; - } + if (!LocaleToResource.TryGetValue(culture, out var resources)) return; + (element.Resources as ResourceDictionary)?.SetItems(resources); } } \ No newline at end of file From 0ea632437d46d8fb2d0e90ed8b9a8af5aa9cb56d Mon Sep 17 00:00:00 2001 From: Zhang Dian <54255897+zdpcdt@users.noreply.github.com> Date: Thu, 16 Oct 2025 16:12:40 +0800 Subject: [PATCH 2/2] fix: fix copilot comment. --- src/Semi.Avalonia/SemiTheme.axaml.cs | 37 +++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/src/Semi.Avalonia/SemiTheme.axaml.cs b/src/Semi.Avalonia/SemiTheme.axaml.cs index 86cacb8..8b3e148 100644 --- a/src/Semi.Avalonia/SemiTheme.axaml.cs +++ b/src/Semi.Avalonia/SemiTheme.axaml.cs @@ -48,12 +48,26 @@ public class SemiTheme : Styles if (TryGetLocaleResource(value, out var resource) && resource is not null) { _locale = value; - (Resources as ResourceDictionary)?.SetItems(resource); + if (Resources is ResourceDictionary rd) + { + rd.SetItems(resource); + } + else + { + foreach (var kv in resource) Resources[kv.Key] = kv.Value; + } } else { _locale = new CultureInfo("zh-CN"); - (Resources as ResourceDictionary)?.SetItems(DefaultResource); + if (Resources is ResourceDictionary rd) + { + rd.SetItems(DefaultResource); + } + else + { + foreach (var kv in DefaultResource) Resources[kv.Key] = kv.Value; + } } } catch @@ -91,13 +105,28 @@ public class SemiTheme : Styles { if (culture is null) return; if (!LocaleToResource.TryGetValue(culture, out var resources)) return; - (application.Resources as ResourceDictionary)?.SetItems(resources); + + if (application.Resources is ResourceDictionary rd) + { + rd.SetItems(resources); + } + else + { + 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; - (element.Resources as ResourceDictionary)?.SetItems(resources); + if (element.Resources is ResourceDictionary rd) + { + rd.SetItems(resources); + } + else + { + foreach (var kv in resources) element.Resources[kv.Key] = kv.Value; + } } } \ No newline at end of file