Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#WPF从其他类更改窗口的属性会导致异常_C#_Wpf_Xaml_Windows 10 - Fatal编程技术网

C#WPF从其他类更改窗口的属性会导致异常

C#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

我试图创建一个自定义窗口,该窗口根据Windows10主题(亮或暗)更改其主题。我能够在运行时听到Windows10主题的变化。但当我设置自定义依赖项属性值(WindowTheme)时,应用程序会引发异常:

引发异常:中的“System.InvalidOperationException” 引发WindowsBase.dll异常: mscorlib.dll中的“System.Reflection.targetingException”

这是我的密码:

Window.cs

Themeutability.cs



从这篇文章中,我知道可以使用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);
}