4

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.

robcsi
  • 264
  • 3
  • 17

3 Answers3

5

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}">
Maxim Nikonov
  • 674
  • 4
  • 13
  • How do I get the Windows theme (dark or light) when the application starts so that I can set that value to Settings.Apptheme? – robcsi Nov 21 '15 at 14:30
  • On start you can use RequestedTheme property of application, it will be of ApplicationTheme type instead of ElementTheme, but it will have same enum values – Maxim Nikonov Nov 23 '15 at 13:26
  • Thanks a lot for the info. I discovered in the meantime that if I don't set the App.RequestedTheme in the app.xaml file, I get what I was looking for. That is, the theme of the app changes to the one that is set in the OS. I had thought before that I needed to do that myself from code. Still, both of your responses were of great help. – robcsi Nov 25 '15 at 16:47
  • 1
    When I try this I get a error on the xaml stating "Invalid binding path 'Settings.AppTheme' : Property 'Settings' can't be found on type 'MainPage'" – AbsoluteSith Apr 26 '16 at 18:39
4

Use ThemeResource instead of StaticResource for the colors which might change at runtime:

{ThemeResource ApplicationPageBackgroundThemeBrush}
sibbl
  • 3,203
  • 26
  • 38
0

The answer to my question is that I don't need to set the App.RequestedTheme property in the app.xaml file in order to have the theme of the application follow the one of the OS.

I just thought that it needed to be done manually by code.

robcsi
  • 264
  • 3
  • 17