-
Notifications
You must be signed in to change notification settings - Fork 54
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add github.com/rudyhuyn/XamlPlus Attached Style Helper
Resolve issue with ToggleSwitch override due to microsoft/microsoft-ui-xaml#7792
- Loading branch information
1 parent
137cc07
commit 2df826b
Showing
5 changed files
with
150 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
59 changes: 59 additions & 0 deletions
59
labs/SettingsControls/src/Helpers/ResourceDictionaryExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
// See the LICENSE file in the project root for more information. | ||
|
||
namespace CommunityToolkit.Labs.WinUI; | ||
|
||
// Adapted from https://github.com/rudyhuyn/XamlPlus | ||
internal static class ResourceDictionaryExtensions | ||
{ | ||
/// <summary> | ||
/// Copies the <see cref="ResourceDictionary"/> provided as a parameter into the calling dictionary, includes overwriting the source location, theme dictionaries, and merged dictionaries. | ||
/// </summary> | ||
/// <param name="destination">ResourceDictionary to copy values to.</param> | ||
/// <param name="source">ResourceDictionary to copy values from.</param> | ||
internal static void CopyFrom(this ResourceDictionary destination, ResourceDictionary source) | ||
{ | ||
if (source.Source != null) | ||
{ | ||
destination.Source = source.Source; | ||
} | ||
else | ||
{ | ||
// Clone theme dictionaries | ||
if (source.ThemeDictionaries != null) | ||
{ | ||
foreach (var theme in source.ThemeDictionaries) | ||
{ | ||
if (theme.Value is ResourceDictionary themedResource) | ||
{ | ||
var themeDictionary = new ResourceDictionary(); | ||
themeDictionary.CopyFrom(themedResource); | ||
destination.ThemeDictionaries[theme.Key] = themeDictionary; | ||
} | ||
else | ||
{ | ||
destination.ThemeDictionaries[theme.Key] = theme.Value; | ||
} | ||
} | ||
} | ||
|
||
// Clone merged dictionaries | ||
if (source.MergedDictionaries != null) | ||
{ | ||
foreach (var mergedResource in source.MergedDictionaries) | ||
{ | ||
var themeDictionary = new ResourceDictionary(); | ||
themeDictionary.CopyFrom(mergedResource); | ||
destination.MergedDictionaries.Add(themeDictionary); | ||
} | ||
} | ||
|
||
// Clone all contents | ||
foreach (var item in source) | ||
{ | ||
destination[item.Key] = item.Value; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
// See the LICENSE file in the project root for more information. | ||
|
||
namespace CommunityToolkit.Labs.WinUI; | ||
|
||
// Adapted from https://github.com/rudyhuyn/XamlPlus | ||
public static partial class StyleExtensions | ||
{ | ||
// Used to distinct normal ResourceDictionary and the one we add. | ||
private sealed class StyleExtensionResourceDictionary : ResourceDictionary | ||
{ | ||
} | ||
|
||
public static ResourceDictionary GetResources(Style obj) | ||
{ | ||
return (ResourceDictionary)obj.GetValue(ResourcesProperty); | ||
} | ||
|
||
public static void SetResources(Style obj, ResourceDictionary value) | ||
{ | ||
obj.SetValue(ResourcesProperty, value); | ||
} | ||
|
||
public static readonly DependencyProperty ResourcesProperty = | ||
DependencyProperty.RegisterAttached("Resources", typeof(ResourceDictionary), typeof(StyleExtensions), new PropertyMetadata(null, ResourcesChanged)); | ||
|
||
private static void ResourcesChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) | ||
{ | ||
if (!(sender is FrameworkElement frameworkElement)) | ||
{ | ||
return; | ||
} | ||
|
||
var mergedDictionaries = frameworkElement.Resources?.MergedDictionaries; | ||
if (mergedDictionaries == null) | ||
{ | ||
return; | ||
} | ||
|
||
var existingResourceDictionary = | ||
mergedDictionaries.FirstOrDefault(c => c is StyleExtensionResourceDictionary); | ||
if (existingResourceDictionary != null) | ||
{ | ||
// Remove the existing resource dictionary | ||
mergedDictionaries.Remove(existingResourceDictionary); | ||
} | ||
|
||
if (e.NewValue is ResourceDictionary resource) | ||
{ | ||
var clonedResources = new StyleExtensionResourceDictionary(); | ||
clonedResources.CopyFrom(resource); | ||
mergedDictionaries.Add(clonedResources); | ||
} | ||
|
||
if (frameworkElement.IsLoaded) | ||
{ | ||
// Only force if the style was applied after the control was loaded | ||
ForceControlToReloadThemeResources(frameworkElement); | ||
} | ||
} | ||
|
||
private static void ForceControlToReloadThemeResources(FrameworkElement frameworkElement) | ||
{ | ||
// To force the refresh of all resource references. | ||
// Note: Doesn't work when in high-contrast. | ||
var currentRequestedTheme = frameworkElement.RequestedTheme; | ||
frameworkElement.RequestedTheme = currentRequestedTheme == ElementTheme.Dark | ||
? ElementTheme.Light | ||
: ElementTheme.Dark; | ||
frameworkElement.RequestedTheme = currentRequestedTheme; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters