Click here to Skip to main content
15,888,341 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm developing a test app with WPF C# that changes MainWindow's background when the Windows 10 App mode changes. I.e. the window background switches to the color "black" when Windows 10 App Mode switches to "Dark" and to color "white" when the App Mode switches to "Light". I have added the following code in MainWindow.xaml.cs. But while I'm running the test app if I open the Windows Settings App and change the App Mode, the test app's background does not change. Any idea why?

C#
<pre>using Microsoft.Win32;
using System;
using System.Globalization;
using System.Management;
using System.Security.Principal;
using System.Windows;
using System.Windows.Media;

namespace WpfApp1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

		private const string RegistryKeyPath = @"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize";
		private const string RegistryValueName = "AppsUseLightTheme";

		public void CheckRegKeyExists()
		{
			if (Registry.GetValue(RegistryValueName,RegistryValueName, null) == null)
			{
				Background = Brushes.AliceBlue;
			}
			
		}

		private enum WindowsTheme
		{
			Light,
			Dark
		}

		public void WatchTheme()
		{
			var currentUser = WindowsIdentity.GetCurrent();
			string query = string.Format(
				CultureInfo.InvariantCulture,
				@"SELECT * FROM RegistryValueChangeEvent WHERE Hive = 'HKEY_USERS' AND KeyPath = '{0}\\{1}' AND ValueName = '{2}'",
				currentUser.User.Value,
				RegistryKeyPath.Replace(@"\", @"\\"),
				RegistryValueName);

			try
			{
				var watcher = new ManagementEventWatcher(query);
				watcher.EventArrived += (sender, args) =>
				{
					WindowsTheme newWindowsTheme = GetWindowsTheme();
					// React to new theme
					if (newWindowsTheme == WindowsTheme.Light)
					{
						Background = Brushes.WhiteSmoke;
						MessageBox.Show("Light");
					}
					else
					{
						Background = Brushes.DarkGray;
						MessageBox.Show("Dark");
					}
					
					
				};

				// Start listening for events
				watcher.Start();
			}
			catch (Exception)
			{
				// This can fail on Windows 7
			}

			WindowsTheme initialTheme = GetWindowsTheme();
		}

		private static WindowsTheme GetWindowsTheme()
		{
			using (RegistryKey key = Registry.CurrentUser.OpenSubKey(RegistryKeyPath))
			{
				object registryValueObject = key?.GetValue(RegistryValueName);
				if (registryValueObject == null)
				{
					return WindowsTheme.Light;
				}

				int registryValue = (int)registryValueObject;

				return registryValue > 0 ? WindowsTheme.Light : WindowsTheme.Dark;
			}
		}

	}
}


I have also added reference to System.Management.dll

Original source of the above code


What I have tried:

Tried to monitor registry key changes using System.Management.dll
Posted
Updated 26-Nov-20 2:06am
Comments
CHill60 26-Nov-20 7:53am    
For starters get rid of
catch (Exception)
			{
				// This can fail on Windows 7
			}
or better, handle the actual exception you want to ignore and report the rest. It might give you a clue as to what is going on

1 solution

Try subscribing to the SystemEvents.UserPreferenceChanged event[^].

In theory, this event should be raised when the users changes their app mode settings.
 
Share this answer
 
Comments
Member 13337867 26-Nov-20 9:00am    
OK I'll try what you have suggested. But can you tell me what is wrong with my current code and how subscribing to the `SystemEvents.UserPreferenceChanged` event is a better alternative?
Richard Deeming 26-Nov-20 9:09am    
The UserPreferenceChanged event should be raised for every user preference change, and should require fewer resources than a WMI registry change monitor.

However, I haven't been able to verify whether the event is actually raised for the new "app mode" setting.

If it is, and it works, then that makes it better than your current code, which doesn't. :)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900