我正在尝试在 WPF 中定义一个应用程序范围的主题。我首先将默认窗口背景设置为黑色。在我的全局资源中(当前在 App.xaml 中),我设置了以下内容
<Application x:Class="f12dotnet.ThemeSandbox.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.WindowBrushKey}" Color="#444" />
</Application.Resources>
</Application>
我的用户界面中有一个
ListBox
,它仍然是白色的。将 SystemColors.ControlBrushKey
设置为透明没有帮助。
在默认列表框模板中,我在最顶部看到一个设置器,将
Background
属性(如我所期望的)设置为SystemColors.WindowBrushKey
。尽管如此,背景还是白色的。
<Style x:Key="{x:Type ListBox}"
TargetType="{x:Type ListBox}">
<Setter Property="Background"
Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
使用
DependencyPropertyHelper.GetValueSource
告诉我来源是 DefaultStyle
,这意味着,根据 MSDN:
源来自默认样式的setter。默认样式来自当前主题。
那么那是哪里?
在
ListBox
模板的下方,我注意到以下内容:
<!-- [[Aero2.NormalColor]] -->
<SolidColorBrush x:Key="ListBox.Static.Background" Color="#FFFFFFFF" />
<SolidColorBrush x:Key="ListBox.Static.Border" Color="#FFABADB3" />
我怀疑这就是罪魁祸首,因为出于绝望,我实际上在 WPF GitHub 存储库中搜索了“#FFFFFF”,除此之外没有发现任何有趣的东西。有趣的是,它是在控件模板中定义的,而不是在经典主题 XAML 中。
SystemColors.WindowBrushKey
一样“覆盖”此画笔吗?
ListBox.Static.Background
画笔,我仍然必须对许多其他控件执行相同的操作,因此创建默认样式(从一个基本样式继承)实际上似乎是更好的方法。我只是好奇,深入兔子洞,想查明白色背景的起源并在那里“阻止它”。
此外,显然有人“十年前遇到过类似的问题”,并设法按照我想要的方式解决它并期望它起作用。但它对我、今天或 Windows 11 不起作用。我建议您检查您的元素中实际使用了哪个模板。我怀疑这将是您提供链接的模板。该模板使用“Value =”{DynamicResource”。据我所知,在 Windows 8 之前,这是有效的。并且具有覆盖系统密钥的解决方案在 Windows 7 中完美地完成了这项工作。
您可以通过以下方式获取配置中的元素使用的模板:
在 Studio 设计器中,打开包含所需元素的 XAML(通常为此,我会创建一个包含一个元素的新测试空窗口);
<SolidColorBrush x:Key="ListBox.Static.Background" Color="#FFFFFFFF"/>
<SolidColorBrush x:Key="ListBox.Static.Border" Color="#FFABADB3"/>
<SolidColorBrush x:Key="ListBox.Disabled.Background" Color="#FFFFFFFF"/>
<SolidColorBrush x:Key="ListBox.Disabled.Border" Color="#FFD9D9D9"/>
<Style x:Key="ListBoxStyle1" TargetType="{x:Type ListBox}">
<Setter Property="Background" Value="{StaticResource ListBox.Static.Background}"/>
<Setter Property="BorderBrush" Value="{StaticResource ListBox.Static.Border}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
<Setter Property="ScrollViewer.PanningMode" Value="Both"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBox}">
<Border x:Name="Bd" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="1" SnapsToDevicePixels="true">
<ScrollViewer Focusable="false" Padding="{TemplateBinding Padding}">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</ScrollViewer>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="Bd" Value="{StaticResource ListBox.Disabled.Background}"/>
<Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource ListBox.Disabled.Border}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsGrouping" Value="true"/>
<Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>