diff --git a/src/Uno.Toolkit.UI/Behaviors/ResourceExtensions.cs b/src/Uno.Toolkit.UI/Behaviors/ResourceExtensions.cs index c22fa75c4..3f7f1dfbc 100644 --- a/src/Uno.Toolkit.UI/Behaviors/ResourceExtensions.cs +++ b/src/Uno.Toolkit.UI/Behaviors/ResourceExtensions.cs @@ -36,7 +36,11 @@ private static void OnResourcesChanged(DependencyObject d, DependencyPropertyCha { if (d is Control control && e.NewValue is ResourceDictionary newResources) { +#if !HAS_UNO + control.Resources = newResources.DeepClone(); +#else control.Resources = newResources; +#endif } } } diff --git a/src/Uno.Toolkit.UI/Extensions/ResourceDictionaryExtensions.cs b/src/Uno.Toolkit.UI/Extensions/ResourceDictionaryExtensions.cs new file mode 100644 index 000000000..1555bb100 --- /dev/null +++ b/src/Uno.Toolkit.UI/Extensions/ResourceDictionaryExtensions.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Uno.Extensions; +using Uno.Logging; + +#if IS_WINUI +using Microsoft.UI.Xaml; +#else +using Windows.UI.Xaml; +#endif + +namespace Uno.Toolkit.UI; + +internal static class ResourceDictionaryExtensions +{ + private static readonly ILogger _logger = typeof(ResourceDictionaryExtensions).Log(); + + /// + /// Creates a deep clone of the given . + /// + /// The resource dictionary to clone. + /// A deep clone of the resource dictionary. + /// Only the resource dictionary, its nesting theme, and merged dictionaries are deep-cloned. Not their values. + public static ResourceDictionary DeepClone(this ResourceDictionary rd) + { + try + { + if (rd.Source is not null) return new ResourceDictionary() { Source = rd.Source }; + + var result = new ResourceDictionary(); + + if (rd.ThemeDictionaries is { }) + { + foreach (var (key, value) in rd.ThemeDictionaries) + { + result.ThemeDictionaries[key] = (value as ResourceDictionary)?.DeepClone() ?? value; + } + } + if (rd.MergedDictionaries is { }) + { + foreach (var md in rd.MergedDictionaries) + { + result.MergedDictionaries.Add(md.DeepClone()); + } + } + foreach (var (key, value) in rd) + { + result[key] = value; + } + + return result; + } + catch (Exception e) + { + _logger.Error("Failed to clone the resource-dictionary", e); + throw; + } + } +}