C# 通过XAML将Windows重音颜色设置为WPF窗口背景,并侦听重音颜色的更改
我正在创建一个WPF项目,它使用Windows10的强调色作为我的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
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)}">