Home > Software design >  Changing the highlight bar in a WPF ComboBox dropdown list - Visual Studio 2022 and Windows 11
Changing the highlight bar in a WPF ComboBox dropdown list - Visual Studio 2022 and Windows 11

Time:09-22

I have several years of software development but I am brand new to WPF. I just started working with a new company that uses WPF. I am learning it on the job.

I have been looking all over for a solution to this problem. I have seen a couple of solutions but when I tried them they never worked. One solution I found here was this

<ComboBox.Resources>
    <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="#FFE89519" />
    <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey }" Color="#FFE89519" />
</ComboBox.Resources>

This did not work. In the comments of one of the answers with this solution the person said it does not work in Windows 8. Don't ya just love consistency. Apparently this is also true of Window 11.

Another solution said to create a MultiTrigger like this

<ComboBoxItem>
    <MultiTrigger>
        <MultiTrigger.Conditions>
            <Condition Property="IsSelected" Value="True"/>
            <Condition Property="IsMouseOver" Value="False"/>
            <Condition Property="IsKeyboardFocused" Value="False"/>
        </MultiTrigger.Conditions>
        <Setter Property="Background" TargetName="MyComboBox" Value="#D1E8FF"/>
        <Setter Property="BorderBrush" TargetName="MyComboBox" Value="#66A7E8"/>
    </MultiTrigger>
</ComboBoxItem>

But this just generated errors in my code. It did not know how to deal with IsSelected, IsMouseOver or IsKeyboardFocused. I found that odd seeing that they are listed as properties of the ComboBox on Microsoft web site.

Does anyone have any other solutions that work in 2022 and not just 2002?

All I want to do is change the color of the highlight bar when using the Up and Down arrow keys on the ComboBox dropdown list.

CodePudding user response:

Item templates are set by the Windows theme. When you create your Custom Control, its default template is written to the Themes\Generic.xaml file. For the Aero theme, this would be Themes\Aero.xaml, and so on.
The reason that the solutions you found don't work is that they are for templates used in Windows 7 themes. Since Windows 8 (or 8.1 - I don't remember exactly) element templates have been changed.
For the current version of Windows 10, the ComboBoxItem template is:

<Style x:Key="FocusVisual">
    <Setter Property="Control.Template">
        <Setter.Value>
            <ControlTemplate>
                <Rectangle Margin="2" StrokeDashArray="1 2" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" SnapsToDevicePixels="true" StrokeThickness="1"/>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<SolidColorBrush x:Key="ComboBoxItem.ItemsviewHover.Background" Color="#1F26A0DA"/>
<SolidColorBrush x:Key="ComboBoxItem.ItemsviewHover.Border" Color="#A826A0DA"/>
<SolidColorBrush x:Key="ComboBoxItem.ItemsviewSelected.Background" Color="#3D26A0DA"/>
<SolidColorBrush x:Key="ComboBoxItem.ItemsviewSelected.Border" Color="#FF26A0DA"/>
<SolidColorBrush x:Key="ComboBoxItem.ItemsviewSelectedHover.Background" Color="#2E0080FF"/>
<SolidColorBrush x:Key="ComboBoxItem.ItemsviewSelectedHover.Border" Color="#99006CD9"/>
<SolidColorBrush x:Key="ComboBoxItem.ItemsviewSelectedNoFocus.Background" Color="#3DDADADA"/>
<SolidColorBrush x:Key="ComboBoxItem.ItemsviewSelectedNoFocus.Border" Color="#FFDADADA"/>
<SolidColorBrush x:Key="ComboBoxItem.ItemsviewFocus.Border" Color="#FF26A0DA"/>
<SolidColorBrush x:Key="ComboBoxItem.ItemsviewHoverFocus.Background" Color="#5426A0DA"/>
<SolidColorBrush x:Key="ComboBoxItem.ItemsviewHoverFocus.Border" Color="#FF26A0DA"/>
<Style x:Key="ComboBoxItemContainerStyle" TargetType="{x:Type ComboBoxItem}">
    <Setter Property="SnapsToDevicePixels" Value="True"/>
    <Setter Property="Padding" Value="4,1"/>
    <Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
    <Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="BorderBrush" Value="Transparent"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ComboBoxItem}">
                <Border x:Name="Bd" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
                    <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsEnabled" Value="False">
                        <Setter Property="TextElement.Foreground" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                    </Trigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsSelected" Value="False"/>
                            <Condition Property="IsMouseOver" Value="True"/>
                            <Condition Property="IsKeyboardFocused" Value="False"/>
                        </MultiTrigger.Conditions>
                        <Setter Property="Background" TargetName="Bd" Value="{StaticResource ComboBoxItem.ItemsviewHover.Background}"/>
                        <Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource ComboBoxItem.ItemsviewHover.Border}"/>
                    </MultiTrigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsSelected" Value="True"/>
                            <Condition Property="IsMouseOver" Value="False"/>
                            <Condition Property="IsKeyboardFocused" Value="True"/>
                        </MultiTrigger.Conditions>
                        <Setter Property="Background" TargetName="Bd" Value="{StaticResource ComboBoxItem.ItemsviewSelected.Background}"/>
                        <Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource ComboBoxItem.ItemsviewSelected.Border}"/>
                    </MultiTrigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsSelected" Value="True"/>
                            <Condition Property="IsMouseOver" Value="True"/>
                        </MultiTrigger.Conditions>
                        <Setter Property="Background" TargetName="Bd" Value="{StaticResource ComboBoxItem.ItemsviewSelectedHover.Background}"/>
                        <Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource ComboBoxItem.ItemsviewSelectedHover.Border}"/>
                    </MultiTrigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsSelected" Value="True"/>
                            <Condition Property="IsMouseOver" Value="False"/>
                            <Condition Property="IsKeyboardFocused" Value="False"/>
                        </MultiTrigger.Conditions>
                        <Setter Property="Background" TargetName="Bd" Value="{StaticResource ComboBoxItem.ItemsviewSelectedNoFocus.Background}"/>
                        <Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource ComboBoxItem.ItemsviewSelectedNoFocus.Border}"/>
                    </MultiTrigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsSelected" Value="False"/>
                            <Condition Property="IsMouseOver" Value="False"/>
                            <Condition Property="IsKeyboardFocused" Value="True"/>
                        </MultiTrigger.Conditions>
                        <Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource ComboBoxItem.ItemsviewFocus.Border}"/>
                    </MultiTrigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsSelected" Value="False"/>
                            <Condition Property="IsMouseOver" Value="True"/>
                            <Condition Property="IsKeyboardFocused" Value="True"/>
                        </MultiTrigger.Conditions>
                        <Setter Property="Background" TargetName="Bd" Value="{StaticResource ComboBoxItem.ItemsviewHoverFocus.Background}"/>
                        <Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource ComboBoxItem.ItemsviewHoverFocus.Border}"/>
                    </MultiTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

As you can see, the XAML highlight colors are set by the StaticResource keys, so they cannot be changed.
You can set a default style in App where you replace StaticResource with DynamicResource. And then you can change the keys as it was done in Windows 7.

    <Application.Resources>
        <SolidColorBrush x:Key="ComboBoxItem.ItemsviewSelectedHover.Background" Color="#2E0080FF"/>
        <SolidColorBrush x:Key="ComboBoxItem.ItemsviewSelectedHover.Border" Color="#99006CD9"/>
        <!--Others key-->
        <!--In the style, you do not set the key, then it is applied to all elements-->
        <Style TargetType="{x:Type ComboBoxItem}">
            <!--XAML start style-->
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="IsSelected" Value="True"/>
                                    <Condition Property="IsMouseOver" Value="True"/>
                                </MultiTrigger.Conditions>
                                <Setter Property="Background" TargetName="Bd" Value="{DynamicResource ComboBoxItem.ItemsviewSelectedHover.Background}"/>
                                <Setter Property="BorderBrush" TargetName="Bd" Value="{DynamicResource ComboBoxItem.ItemsviewSelectedHover.Border}"/>
                            </MultiTrigger>
            <!--XAML style completion-->
<ComboBox.Resources>
        <SolidColorBrush x:Key="ComboBoxItem.ItemsviewSelectedHover.Background" Color="#FFE89519"/>
        <SolidColorBrush x:Key="ComboBoxItem.ItemsviewSelectedHover.Border" Color="#FFE89519"/>
</ComboBox.Resources>
  • Related