Change themes in Windows 10 UWP App Programmatically

I managed to change the theme using this.RequestedTheme = ElementTheme.Dark; But I need the whole level of the application, since it only changes the theme of the current page to darkness.

Whenever I try to execute this App.Current.RequestedTheme = ApplicationTheme.Dark; I always get this error

An exception of type "System.NotSupportedException" occurred in UWPApp.exe, but was not processed in the user code

Is there a way to change the whole theme of the application from Light to Dark or vice versa?

I am using VS2015

+10
source share
4 answers

Updated answer with what I finally decided.

I used the settings class, which contains all the application settings, including the theme you want to use. Since the theme can only be set when it starts, we need to make sure that it is installed. This is the code I used:

In the App.xaml.cs file:

 public App() { //Load settings AppSettings.LoadSettings(); this.RequestedTheme = AppSettings.SelectedTheme; this.InitializeComponent(); } 

In the App.xaml file, make sure to remove this property:

  RequestedTheme="Light" 

If you do not delete it, it always lights up by default without changing it.

Thus, the user can select a theme, it will be stored and used when the application starts. Just download it and apply it in the application initialization phase.

+15
source

Application RequestedTheme can only be updated in the constructor. However (as you have discovered) the RequestedTheme page can be refreshed at any time at run time.

This is really annoying, I know, and not much information about this situation other than this MSDN page:

https://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.application.requestedtheme?f=255&MSPPError=-2147217396

The theme can be installed only when the application starts, and not during its launch. Attempting to set RequestedTheme during application startup throws an exception (NotSupportedException for Microsoft.NET code). If you give the user the opportunity to select a theme that is part of the user interface of the application, you must save this parameter in the application data and apply it when the application restarts.

There should be workarounds, but they will be very dumb. Microsoft does this in its official applications, such as Groove, though ...

My solution is updating the theme at the element level, not at the application level.

  • Create your own BasePage (inherited from the page)
  • Save your settings under a static class and create an event to track model changes.
  • In your BasePage constructor, listen for this event and apply the changes when available.

I can’t provide an example of the code right now (since I am very busy today), but this is by far the most effective way IMHO.

+9
source

I found another solution that helped me a lot. If the application has a root frame that loads pages (which is the default), I could set the requested theme for this root frame to the desired value, and the theme of the application was changed without restarting. The code looks like this:

 // Set theme for window root. if (Window.Current.Content is FrameworkElement frameworkElement) { frameworkElement.RequestedTheme = theme; } 

I got this snippet from the Windows Template Studio GitHub repository here , so this seems to be the best way to do this.

+4
source

I find that Axnull's answer is most useful as it allows you to set a theme while the application is running. After more than a good working day, I was able to install the application theme on the fly and save it in memory for the next run, giving the user control using ToggleButton .

First, I created a settings class with Theme property that automatically saves the current settings:

 class AppSettings { public const ElementTheme DEFAULTTHEME = ElementTheme.Light; public const ElementTheme NONDEFLTHEME = ElementTheme.Dark; const string KEY_THEME = "appColourMode"; static ApplicationDataContainer LOCALSETTINGS = ApplicationData.Current.LocalSettings; /// <summary> /// Gets or sets the current app colour setting from memory (light or dark mode). /// </summary> public static ElementTheme Theme { get { // Never set: default theme if (LOCALSETTINGS.Values[KEY_THEME] == null) { LOCALSETTINGS.Values[KEY_THEME] = (int)DEFAULTTHEME; return DEFAULTTHEME; } // Previously set to default theme else if ((int)LOCALSETTINGS.Values[KEY_THEME] == (int)DEFAULTTHEME) return DEFAULTTHEME; // Previously set to non-default theme else return NONDEFLTHEME; } set { // Error check if (value == ElementTheme.Default) throw new System.Exception("Only set the theme to light or dark mode!"); // Never set else if (LOCALSETTINGS.Values[KEY_THEME] == null) LOCALSETTINGS.Values[KEY_THEME] = (int)value; // No change else if ((int)value == (int)LOCALSETTINGS.Values[KEY_THEME]) return; // Change else LOCALSETTINGS.Values[KEY_THEME] = (int)value; } } } 

Then, the following code was added to the page constructor:

  public MainPage() { this.InitializeComponent(); // Set theme for window root FrameworkElement root = (FrameworkElement)Window.Current.Content; root.RequestedTheme = AppSettings.Theme; SetThemeToggle(AppSettings.Theme); } 

This sets the theme according to the previous selection in the application memory and sets the corresponding switch.

The following method is called when the page loads:

  /// <summary> /// Set the theme toggle to the correct position (off for the default theme, and on for the non-default). /// </summary> private void SetThemeToggle(ElementTheme theme) { if (theme == AppSettings.DEFAULTTHEME) tglAppTheme.IsOn = false; else tglAppTheme.IsOn = true; } 

And this handles the switch toggle:

  /// <summary> /// Switch the app theme between light mode and dark mode, and save that setting. /// </summary> private void ToggleSwitch_Toggled(object sender, RoutedEventArgs e) { FrameworkElement window = (FrameworkElement)Window.Current.Content; if (((ToggleSwitch)sender).IsOn) { AppSettings.Theme = AppSettings.NONDEFLTHEME; window.RequestedTheme = AppSettings.NONDEFLTHEME; } else { AppSettings.Theme = AppSettings.DEFAULTTHEME; window.RequestedTheme = AppSettings.DEFAULTTHEME; } } 

All of the above code is generated for the following ToggleButton switch:

 <ToggleSwitch Name="tglAppTheme" Header="Theme" OffContent="Light" OnContent="Dark" IsOn="False" Toggled="ToggleSwitch_Toggled" /> 

This setup is quite simple and may possibly save someone from hard work.

0
source

All Articles