设置组合框前景色的最简单方法
easiest way to style combobox's foreground color
我在我的全局字典中将 TextBlock
的前景设置为白色,这种样式也应用于 Combobox
,这使得组合框选项不可读。我找不到为 windows 8 或更高版本设置 Combobox
背景样式的简单方法。所以我决定暂时可以使用默认的 Combobox
样式,但我似乎仍然找不到简单的解决方案。我尝试设置 Combobox
的 foreground
、Combobox.Resources
下的 TextBlock
样式和 ComboBoxItem
样式,但没有成功。
如果我可以将组合框的背景设置为黑色而不复制整个 Combobox
的控件模板,那将是理想的选择。如果没有,那么如果我可以在我的字典中设置 Combobox
的前景样式,那将是最好的,但我愿意接受解决方案。
编辑:包含最少示例
Dictionary1.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1">
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="WhiteSmoke"/>
</Style>
</ResourceDictionary>
App.xaml:
<Application x:Class="WpfApplication1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionary1.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
mainwindow.xaml
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525"
Closing="Window_Closing">
<Grid>
<ComboBox Text="test" Height="50" Width="100" Foreground="Black">
<ComboBox.Resources>
<Style TargetType="ComboBoxItem">
<Style.Setters>
<Setter Property="Foreground" Value="Black"/>
</Style.Setters>
</Style>
<Style TargetType="TextBlock">
<Style.Setters>
<Setter Property="Foreground" Value="Black"/>
</Style.Setters>
</Style>
</ComboBox.Resources>
<ComboBoxItem>test1</ComboBoxItem>
<ComboBoxItem>test2</ComboBoxItem>
</ComboBox>
</Grid>
</Window>
请注意前景的 none = 黑色。我正在使用 windows 10。
如果仅在 ComboBox 中显示文本:
<Style TargetType="{x:Type ComboBox}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" />
</Style>
如果要更改背景,需要创建一个ControlTemplate 副本。在官方 Win8 和更高版本的模板中,存在一个问题 - 不是在 ComboBox 中,而是在 ToggleButton 原语中。这是控件链:ComboBoxTemplate > ToggleButton > ToggleButtonTemplate。但是,背景和其他画笔的 TemplateBinding
不存在于 TogglebuttonTemplate 中,因此对背景的任何更改都不会传播到 ToggleButton 的子级。唯一的方法是创建控件的副本并通过 TemplateBinding ToggleButton 模板连接缺失的部分。但是,我不确定 ComboBox 是否会在 Windows.
的其他版本上保留本机 OS 外观
我尝试覆盖 ToggleButton 原语,但它没有 ComboBox 的 ToggleButton 使用的自定义模板。
这里的问题是您只能在不受限制的范围内对控件应用隐式样式。对于其他元素,范围仅限于 DataTemplate 或 ControlTemplate。这里的隐式样式是在Resources
中定义的并且没有指定x:Key
(实际上x:Key
将隐式设置为TargetType)。
您在此处定位的 TextBlock
是 ComboBox
模板范围内的那个,因此它不能与某些隐式样式或某些从外部继承的样式一起应用。但是,如果没有任何其他覆盖,应用程序资源中定义的全局样式可以将样式应用于所有元素。
所以你在这里有一些选择。您可以重新模板化 ComboBoxItem
,但它需要更多代码。如果这不是一个选项,您可以尝试将 TextBlock
的全局样式与一些触发器一起应用,如下所示:
<Setter Property="Foreground" Value="WhiteSmoke"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsEnabled,
RelativeSource={RelativeSource AncestorType=ComboBox}}" Value="True">
<Setter Property="Foreground" Value="Black"/>
</DataTrigger>
</Style.Triggers>
Trigger
监听 ComboBox
的任何父级,如果启用,TextBlock
将具有另一种样式(Foreground
设置为 Black
).当然,如您所见,Trigger 属于 ResourceDictionary
中定义的 Style。所有其他 TextBlock
仍然具有它们的全局样式(Foreground
设置为 WhiteSmoke
)。
无论如何,您需要在应用程序的资源或同一级别中覆盖 ResoureDictionary
中定义的样式。 Trigger
只是一种过滤方式,可以 applied/overridden.
我在我的全局字典中将 TextBlock
的前景设置为白色,这种样式也应用于 Combobox
,这使得组合框选项不可读。我找不到为 windows 8 或更高版本设置 Combobox
背景样式的简单方法。所以我决定暂时可以使用默认的 Combobox
样式,但我似乎仍然找不到简单的解决方案。我尝试设置 Combobox
的 foreground
、Combobox.Resources
下的 TextBlock
样式和 ComboBoxItem
样式,但没有成功。
如果我可以将组合框的背景设置为黑色而不复制整个 Combobox
的控件模板,那将是理想的选择。如果没有,那么如果我可以在我的字典中设置 Combobox
的前景样式,那将是最好的,但我愿意接受解决方案。
编辑:包含最少示例
Dictionary1.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1">
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="WhiteSmoke"/>
</Style>
</ResourceDictionary>
App.xaml:
<Application x:Class="WpfApplication1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionary1.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
mainwindow.xaml
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525"
Closing="Window_Closing">
<Grid>
<ComboBox Text="test" Height="50" Width="100" Foreground="Black">
<ComboBox.Resources>
<Style TargetType="ComboBoxItem">
<Style.Setters>
<Setter Property="Foreground" Value="Black"/>
</Style.Setters>
</Style>
<Style TargetType="TextBlock">
<Style.Setters>
<Setter Property="Foreground" Value="Black"/>
</Style.Setters>
</Style>
</ComboBox.Resources>
<ComboBoxItem>test1</ComboBoxItem>
<ComboBoxItem>test2</ComboBoxItem>
</ComboBox>
</Grid>
</Window>
请注意前景的 none = 黑色。我正在使用 windows 10。
如果仅在 ComboBox 中显示文本:
<Style TargetType="{x:Type ComboBox}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" />
</Style>
如果要更改背景,需要创建一个ControlTemplate 副本。在官方 Win8 和更高版本的模板中,存在一个问题 - 不是在 ComboBox 中,而是在 ToggleButton 原语中。这是控件链:ComboBoxTemplate > ToggleButton > ToggleButtonTemplate。但是,背景和其他画笔的 TemplateBinding
不存在于 TogglebuttonTemplate 中,因此对背景的任何更改都不会传播到 ToggleButton 的子级。唯一的方法是创建控件的副本并通过 TemplateBinding ToggleButton 模板连接缺失的部分。但是,我不确定 ComboBox 是否会在 Windows.
我尝试覆盖 ToggleButton 原语,但它没有 ComboBox 的 ToggleButton 使用的自定义模板。
这里的问题是您只能在不受限制的范围内对控件应用隐式样式。对于其他元素,范围仅限于 DataTemplate 或 ControlTemplate。这里的隐式样式是在Resources
中定义的并且没有指定x:Key
(实际上x:Key
将隐式设置为TargetType)。
您在此处定位的 TextBlock
是 ComboBox
模板范围内的那个,因此它不能与某些隐式样式或某些从外部继承的样式一起应用。但是,如果没有任何其他覆盖,应用程序资源中定义的全局样式可以将样式应用于所有元素。
所以你在这里有一些选择。您可以重新模板化 ComboBoxItem
,但它需要更多代码。如果这不是一个选项,您可以尝试将 TextBlock
的全局样式与一些触发器一起应用,如下所示:
<Setter Property="Foreground" Value="WhiteSmoke"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsEnabled,
RelativeSource={RelativeSource AncestorType=ComboBox}}" Value="True">
<Setter Property="Foreground" Value="Black"/>
</DataTrigger>
</Style.Triggers>
Trigger
监听 ComboBox
的任何父级,如果启用,TextBlock
将具有另一种样式(Foreground
设置为 Black
).当然,如您所见,Trigger 属于 ResourceDictionary
中定义的 Style。所有其他 TextBlock
仍然具有它们的全局样式(Foreground
设置为 WhiteSmoke
)。
无论如何,您需要在应用程序的资源或同一级别中覆盖 ResoureDictionary
中定义的样式。 Trigger
只是一种过滤方式,可以 applied/overridden.