robcsi robcsi - 3 months ago 37
C# Question

How to programmatically change background theme of Win 8.1 or Win 10 UWP app?

I have an app for Windows Phone 8.1 and a UWP version of it. I'd like to change the background of the apps dynamically when it is changed in Windows.

Use case would be:


  1. Start the app, the background theme is dark.

  2. Press the home button on the phone

  3. Change the background theme to light

  4. Go back to the app (basically switch to it from the background)

  5. The theme of the app would change automatically to the new theme



I'd like it to be done like this, without a restart. I've seen this in other apps, so it has to be possible somehow, but I can't figure out.

If a restart is required, that is fine too as solution B.

Thanks.

Answer

I would suggest to create settings singleton class that will store AppTheme state and implements INotifyPropertyChanged interface

public class Settings : INotifyPropertyChanged
{
    private static volatile Settings instance;
    private static readonly object SyncRoot = new object();
    private ElementTheme appTheme;

    private Settings()
    {
        this.appTheme = ApplicationData.Current.LocalSettings.Values.ContainsKey("AppTheme")
                            ? (ElementTheme)ApplicationData.Current.LocalSettings.Values["AppTheme"]
                            : ElementTheme.Default;
    }

    public static Settings Instance
    {
        get
        {
            if (instance != null)
            {
                return instance;
            }

            lock (SyncRoot)
            {
                if (instance == null)
                {
                    instance = new Settings();
                }
            }

            return instance;
        }
    }

    public ElementTheme AppTheme
    {
        get
        {
            return this.appTheme;
        }

        set
        {
            ApplicationData.Current.LocalSettings.Values["AppTheme"] = (int)value;
            this.OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

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

Than, you can create Property Settings on page, that will return value of singleton and bind RequestedTheme of Page to AppTheme property

<Page
    x:Class="SamplePage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    RequestedTheme="{x:Bind Settings.AppTheme, Mode=OneWay}">