C#WPF从其他类更改窗口的属性会导致异常
我试图创建一个自定义窗口,该窗口根据Windows10主题(亮或暗)更改其主题。我能够在运行时听到Windows10主题的变化。但当我设置自定义依赖项属性值(WindowTheme)时,应用程序会引发异常: 引发异常:中的“System.InvalidOperationException” 引发WindowsBase.dll异常: mscorlib.dll中的“System.Reflection.targetingException” 这是我的密码: Window.cs Themeutability.csC#WPF从其他类更改窗口的属性会导致异常,c#,wpf,xaml,windows-10,C#,Wpf,Xaml,Windows 10,我试图创建一个自定义窗口,该窗口根据Windows10主题(亮或暗)更改其主题。我能够在运行时听到Windows10主题的变化。但当我设置自定义依赖项属性值(WindowTheme)时,应用程序会引发异常: 引发异常:中的“System.InvalidOperationException” 引发WindowsBase.dll异常: mscorlib.dll中的“System.Reflection.targetingException” 这是我的密码: Window.cs Themeutabili
从这篇文章中,我知道可以使用INotifyPropertyChanged实现它,但我不知道如何在我的案例中实现它
注意:WindowTheme属性的类型为enum,其值为Light、Dark、Default管理EventWatcher。应用程序的UI线程中显然没有调用EventArrized处理程序 依赖项属性只能在创建所属对象的线程中访问 使用窗口的调度程序将执行封送到创建窗口的线程,即UI线程:
public void SwitchTheme(Theme theme)
{
Dispatcher.Invoke(() => WindowTheme = theme);
}
确保
WindowTheme=theme代码>在UI线程中调用。e、 g.通过Dispatcher.Invoke(()=>WindowTheme=theme)代码>感谢它的工作,Application.Current.Dispatcher.Invoke(()=>WindowTheme=theme);
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Management;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
using UWPHost.Enums;
namespace UWPHost.Utilities
{
public class ThemeUtility
{
private const string ThemeRegistry= @"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize";
private const string RegistryValue= "AppsUseLightTheme";
private readonly string query;
private readonly WindowsIdentity CurrentUser;
ManagementEventWatcher ThemeWatcher;
Window window;
public ThemeUtility()
{
CurrentUser = WindowsIdentity.GetCurrent();
query= string.Format(CultureInfo.InvariantCulture,@"SELECT * FROM RegistryValueChangeEvent WHERE Hive = 'HKEY_USERS' AND KeyPath = '{0}\\{1}' AND ValueName = '{2}'", CurrentUser.User.Value,ThemeRegistry.Replace(@"\", @"\\"),RegistryValue);
}
public void Init(Window window)
{
this.window = window;
InitSystemThemeWatcher();
}
private void InitSystemThemeWatcher()
{
try
{
ThemeWatcher = new ManagementEventWatcher(query);
ThemeWatcher.EventArrived += (sender, args) =>
{
//This code is executed when windows 10 theme changes
if(GetSystemTheme()==Theme.Dark)
{
//Here i'm setting the property of window
window.SwitchTheme(Theme.Dark);
}
else
{
window.SwitchTheme(Theme.Light);
}
};
ThemeWatcher.Start();
}
catch(Exception)
{
throw new Exception("Error Unable to add theme listener.");
}
Theme initialTheme = GetSystemTheme();
}
private static Theme GetSystemTheme()
{
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(ThemeRegistry))
{
object registryValueObject = key?.GetValue(RegistryValue);
if (registryValueObject == null)
{
return Theme.Light;
}
int registryValue = (int)registryValueObject;
return registryValue > 0 ? Theme.Light : Theme.Dark;
}
}
}
}
public void SwitchTheme(Theme theme)
{
Dispatcher.Invoke(() => WindowTheme = theme);
}