How to change SystemAccentColor at runtime (UWP)?

Viewed 858

The app has a GridView in which each item is a color that the user can choose to customize the UI overriding the default SystemAccentColor (the one is defined by user on their system). I managed to get the color of the item but even though I assign it as new value for SystemAccentColor I am not able to update the UI.

private void GridView_ItemClick(object sender, ItemClickEventArgs e)
{
        // FIRST APROACH -----

        GridViewItem gridViewItem = GVColors.ContainerFromItem(e.ClickedItem) as GridViewItem;

        Ellipse ellipseItem = gridViewItem.FindDescendant<Ellipse>();

        var theColor = (SolidColorBrush)ellipseItem.Fill;

        Application.Current.Resources["SystemAccentColor"] = theColor;


        // SECOND APPROACH ----

        Windows.UI.Color theColor2 = new Windows.UI.Color
        {
            A = 1,
            R = 176,
            G = 37,
            B = 37
        };

        var root = (FrameworkElement)Window.Current.Content;
        root.Resources["SystemAccentColor"] = theColor2;
}

I'm currently reading this blog entry XAML Brewer, by Diederik Krols: Using a Dynamic System Accent Color in UWP but I want to know if the community knows another approach to change the accent color at runtime (or a method that I'm not aware of to Update/refresh the UI).

2 Answers

I assign it as new value for SystemAccentColor I am not able to update the UI.

Since you statically bind SystemAccentColor and it doesn't implement INotifyPropertyChanged interface, event though the value of SystemAccentColor changes, the UI which bound with it won't update directly.

Based on your requirement, you can add a class which implements INotifyPropertyChanged interface and add the SystemAccentColor as property in it. Then init the class instance in Application.Resources. After that, bind the UI with the SystemAccentColor property. For example, I create a class named SystemAccentColorSetting.

SystemAccentColorSetting.cs:

public class SystemAccentColorSetting : INotifyPropertyChanged
{
    private SolidColorBrush systemAccentColor = new SolidColorBrush(Colors.Red);
    public SolidColorBrush SystemAccentColor
    {
        get { 
            return systemAccentColor; 
        }
        set { 
            systemAccentColor = value; OnPropertyChanged(); 
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

App.xaml:

<Application.Resources>
    <ResourceDictionary>
        <local:SystemAccentColorSetting x:Key="SystemAccentColorSetting"/>
    </ResourceDictionary>
</Application.Resources>

Usage:

Assume that we bind the Background of Button with the SystemAccentColor property.

.xaml:

<Button x:Name="MyButton" Background="{Binding SystemAccentColor, Source={StaticResource SystemAccentColorSetting}}">hello</Button>

.cs:

If you want to change the value of Background, just change the SystemAccentColor property.

private void GridView_ItemClick(object sender, ItemClickEventArgs e)
{
    GridViewItem gridViewItem = GVColors.ContainerFromItem(e.ClickedItem) as GridViewItem;
    Ellipse ellipseItem = gridViewItem.FindDescendant<Ellipse>();
    var theColor = (SolidColorBrush)ellipseItem.Fill;

    ((SystemAccentColorSetting)Application.Current.Resources["SystemAccentColorSetting"]).SystemAccentColor = theColor;
}

Starting from Win 10 1809 (build 17763), you can use the ColorPaletteResources Class. By using it, you can change not only the Accent color at runtime, but also all the other system default colors for UI controls.

Due to a bug, you forst have to declare that ColorPaletteResources object into your App's XAML resources (with a key) and then you can use it at runtime.

Another bug is that, from what I have experimented some time ago, you can only change the Accent color for now, so you are lucky.

To see it in action, you can download Fluent XAML Theme Editor from the Windows Store or from GitHub.

Here is the link to the class itself and to some guidelines on how to use it.

Related