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# 通过XAML将Windows重音颜色设置为WPF窗口背景,并侦听重音颜色的更改_C#_Wpf_Xaml_Data Binding_Windows 10 - Fatal编程技术网

C# 通过XAML将Windows重音颜色设置为WPF窗口背景,并侦听重音颜色的更改

C# 通过XAML将Windows重音颜色设置为WPF窗口背景,并侦听重音颜色的更改,c#,wpf,xaml,data-binding,windows-10,C#,Wpf,Xaml,Data Binding,Windows 10,我正在创建一个WPF项目,它使用Windows10的强调色作为我的WPF主窗口的背景。我能够使用GetImmersiveUserColorSetPreference(),GetImmersiveColorTypeFromName()&GetImmersiveColorFromColorSetEx()获得windows强调色,并且我能够将其用作我的窗口背景。但问题是,当重点颜色更改时,我无法自动更改背景(我必须重新启动以更改背景) 以下是我使用的代码: AccentColors.cs Initia

我正在创建一个WPF项目,它使用Windows10的强调色作为我的WPF主窗口的背景。我能够使用
GetImmersiveUserColorSetPreference()
GetImmersiveColorTypeFromName()
&
GetImmersiveColorFromColorSetEx()
获得windows强调色,并且我能够将其用作我的窗口背景。但问题是,当重点颜色更改时,我无法自动更改背景(我必须重新启动以更改背景)

以下是我使用的代码:

AccentColors.cs

InitializeBrushes()
函数是从
WndProc
WM_DWMCOLORIZATIONCOLORCHANGED
调用的,它帮助我将
SystemAccentBrush
设置为当前系统的强调色,效果很好。但是当我将
SystemAccentBrush
设置为控件的背景时,它不会根据重点颜色更改(但画笔颜色正在更改)

下面是我用来设置SystemAccentBrush作为网格背景的代码:

<Grid x:Name="container" Background="{x:Static common:AccentColors.SystemAccentBrush}">
</Grid>
因此,我尝试将其设置为动态源,如下所示:

{DynamicSource {x:Static common:AccentColors.SystemAccentBrush}}
然后背景消失了

有什么方法可以克服这个问题吗?

用于静态引用,在运行时不会拾取任何更改

引用以符合公共语言规范(CLS)的方式定义的任何静态按值代码实体

如果创建在运行时更改的静态属性,则必须使用绑定并实现类似于
INotifyPropertyChanged
PropertyChanged
事件的静态等效项。自WPF 4.5以来,该功能就得到了支持,目前还没有实现该功能的方法

事件处理程序 按如下所示更改您的属性,并为您的属性创建一个事件
SystemAccentBrushChanged
。使用
null
EventArgs.Empty
SystemAccentBrush
的setter中引发事件

private static Brush systemAccentBrush;
public static Brush SystemAccentBrush
{
   get => systemAccentBrush;
   private set
   {
      if (Equals(systemAccentBrush, value))
         return;

      systemAccentBrush = value;
      SystemAccentBrushChanged?.Invoke(null, EventArgs.Empty);
   }
}

public static event EventHandler SystemAccentBrushChanged;
静态属性更改事件 按如下所示更改属性,创建一个事件
StaticPropertyChanged
,并使用更改的属性名称引发它。此事件可以与不同的属性一起使用

private static Brush systemAccentBrush;

public static Brush SystemAccentBrush
{
   get => systemAccentBrush;
   private set
   {
      if (Equals(systemAccentBrush, value))
         return;

      systemAccentBrush = value;
      OnStaticPropertyChanged();
   }
}

public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged;

private static void OnStaticPropertyChanged([CallerMemberName] string propertyName = null)
{
   StaticPropertyChanged?.Invoke(null, new PropertyChangedEventArgs(propertyName));
}


最后一点注意:虽然通过这种方式支持带有属性更改通知的静态绑定,但您可能需要考虑将静态类迁移到单例。通过这种方式,您可以使
SystemAccentBrush
成为一个非静态属性,实现
INotifyPropertyChanged
并像往常一样绑定该属性,而不需要任何特殊语法或自定义静态事件。

非常感谢它工作得非常好,您的答案非常容易理解。你绝对值得投一票。
private static Brush systemAccentBrush;
public static Brush SystemAccentBrush
{
   get => systemAccentBrush;
   private set
   {
      if (Equals(systemAccentBrush, value))
         return;

      systemAccentBrush = value;
      SystemAccentBrushChanged?.Invoke(null, EventArgs.Empty);
   }
}

public static event EventHandler SystemAccentBrushChanged;
private static Brush systemAccentBrush;

public static Brush SystemAccentBrush
{
   get => systemAccentBrush;
   private set
   {
      if (Equals(systemAccentBrush, value))
         return;

      systemAccentBrush = value;
      OnStaticPropertyChanged();
   }
}

public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged;

private static void OnStaticPropertyChanged([CallerMemberName] string propertyName = null)
{
   StaticPropertyChanged?.Invoke(null, new PropertyChangedEventArgs(propertyName));
}
<Grid Background="{Binding Path=(common:AccentColors.SystemAccentBrush)}">