Skip to content

Commit

Permalink
Merge pull request #1190 from unoplatform/dev/xygu/20240712/resource-…
Browse files Browse the repository at this point in the history
…ext--win-throws

fix: ResourceExtensions throwing ArgumentException on windows
  • Loading branch information
Xiaoy312 authored Jul 13, 2024
2 parents 0ab54f3 + 17f2e6c commit d94eec9
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/Uno.Toolkit.UI/Behaviors/ResourceExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
}
Expand Down
63 changes: 63 additions & 0 deletions src/Uno.Toolkit.UI/Extensions/ResourceDictionaryExtensions.cs
Original file line number Diff line number Diff line change
@@ -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();

/// <summary>
/// Creates a deep clone of the given <see cref="ResourceDictionary"/>.
/// </summary>
/// <param name="rd">The resource dictionary to clone.</param>
/// <returns>A deep clone of the resource dictionary.</returns>
/// <remarks>Only the resource dictionary, its nesting theme, and merged dictionaries are deep-cloned. Not their values.</remarks>
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;
}
}
}

0 comments on commit d94eec9

Please sign in to comment.