wpfui icon indicating copy to clipboard operation
wpfui copied to clipboard

Accent color does not apply to all controls after setting new accent.

Open xzmzm opened this issue 1 year ago • 2 comments

Describe the bug

When calling ApplicationAccentColorManager.Apply(Colors.Red), not all controls have accent color red, they still have old system accent color.

To Reproduce

ApplicationAccentColorManager.Apply(Colors.Red)

Expected behavior

Expect accent color to change for every control.

Screenshots

No response

OS version

Windows 10

.NET version

.NET 8

WPF-UI NuGet version

GitHub repos.

Additional context

Lots of SolidColorBrush resources in WPF UI use Color as dynamic resource. When a new accent color is set, all the Color dynamic resources will be set to new value. However, it is a known problem that dynamic resource such as Color is not so dynamic after all, the SolidColorBrush resources are not actually updated.

Therefore we need to update all the SolidColorBrush resources by ourselves. So I have to use the following code to find all the SolidColorBrush which use dynamic Color and update them according to their Color.

var converter = new ResourceReferenceExpressionConverter();
var brushes = new Dictionary<string, SolidColorBrush>
{
    ["SystemAccentColor"] = ((Color)UiApplication.Current.Resources["SystemAccentColor"]).ToBrush(),
    ["SystemAccentColorPrimary"] = ((Color)UiApplication.Current.Resources["SystemAccentColorPrimary"]).ToBrush(),
    ["SystemAccentColorSecondary"] = ((Color)UiApplication.Current.Resources["SystemAccentColorSecondary"]).ToBrush(),
    ["SystemAccentColorTertiary"] = ((Color)UiApplication.Current.Resources["SystemAccentColorTertiary"]).ToBrush()
};
ResourceDictionary themeDictionary = UiApplication.Current.Resources.MergedDictionaries[0];
foreach (DictionaryEntry entry in themeDictionary)
{
    if (entry.Value is SolidColorBrush brush)
    {
        var dynamicColor = brush.ReadLocalValue(SolidColorBrush.ColorProperty);
        if (dynamicColor is not Color &&
            converter.ConvertTo(dynamicColor, typeof(MarkupExtension)) is DynamicResourceExtension dynamicResource &&
            brushes.ContainsKey((string)dynamicResource.ResourceKey))
        {
            themeDictionary[entry.Key] = brushes[(string)dynamicResource.ResourceKey];
        }
    }
}

xzmzm avatar Aug 02 '24 10:08 xzmzm

So do you set the color before calling this?

thedogecraft avatar Feb 18 '25 03:02 thedogecraft