设置组合框前景色的最简单方法

easiest way to style combobox's foreground color

我在我的全局字典中将 TextBlock 的前景设置为白色,这种样式也应用于 Combobox,这使得组合框选项不可读。我找不到为 windows 8 或更高版本设置 Combobox 背景样式的简单方法。所以我决定暂时可以使用默认的 Combobox 样式,但我似乎仍然找不到简单的解决方案。我尝试设置 ComboboxforegroundCombobox.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)。

您在此处定位的 TextBlockComboBox 模板范围内的那个,因此它不能与某些隐式样式或某些从外部继承的样式一起应用。但是,如果没有任何其他覆盖,应用程序资源中定义的全局样式可以将样式应用于所有元素。

所以你在这里有一些选择。您可以重新模板化 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.