Search code examples
c#wpfbackground

Change background color on a selected Item in WPF with XAML


Basically, I want have a listBox and I want to change the color of the background and foreground of the item that I currently have selected.

I tried this:

<Style TargetType="ListBoxItem" BasedOn="{StaticResource {x:Type ListBoxItem}}">
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="Background" Value="Yellow"/>
                </Trigger>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Background" Value="#FFAFA212"/>
                </Trigger>
            </Style.Triggers>
</Style>

But it didn't do anything at all. I tried searching for it but nothing i tried seemed to work, can anyone help please? This is an App.xaml in a c# project btw.


Solution

  • It's more complicated than you might imagine because of how wpf uses control templates to build controls.

    The templates for a listbox and listboxitem is here:

    https://learn.microsoft.com/en-us/dotnet/desktop/wpf/controls/listbox-styles-and-templates?view=netframeworkdesktop-4.8

    There are a number of ways you could accomplish this but I think the most informative would be to re template.

    Here's something to take a look at. Put this in a parent control ( like the window or grid) resources:

            <Style x:Key="{x:Type ListBoxItem}"
       TargetType="ListBoxItem">
                <Setter Property="SnapsToDevicePixels"
          Value="true" />
                <Setter Property="OverridesDefaultStyle"
          Value="true" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="ListBoxItem">
                            <Border x:Name="Border"
                Padding="2"
                SnapsToDevicePixels="true">
                                <Border.Background>
                                    <SolidColorBrush Color="Transparent" />
                                </Border.Background>
                                <VisualStateManager.VisualStateGroups>
                                    <VisualStateGroup x:Name="SelectionStates">
                                        <VisualState x:Name="Unselected" />
                                        <VisualState x:Name="Selected">
                                            <Storyboard>
                                                <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
                                                Storyboard.TargetProperty="(Panel.Background).
                    (SolidColorBrush.Color)">
                                                    <EasingColorKeyFrame KeyTime="0"
                                         Value="Yellow" />
                                                </ColorAnimationUsingKeyFrames>
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="SelectedUnfocused">
                                            <Storyboard>
                                                <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
                                                Storyboard.TargetProperty="(Panel.Background).
                    (SolidColorBrush.Color)">
                                                    <EasingColorKeyFrame KeyTime="0"
                                         Value="Yellow" />
                                                </ColorAnimationUsingKeyFrames>
                                            </Storyboard>
                                        </VisualState>
                                    </VisualStateGroup>
                                    <VisualStateGroup  x:Name="CommonStates">
                                        <VisualState x:Name="Normal"/>
    
                                        <VisualState x:Name="MouseOver">
                                            <Storyboard>
                                                <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
                                                Storyboard.TargetProperty="(Panel.Background).
                    (SolidColorBrush.Color)">
                                                    <EasingColorKeyFrame KeyTime="0"
                                         Value="#FFAFA212" />
                                                </ColorAnimationUsingKeyFrames>
                                            </Storyboard>
                                        </VisualState>
                                    </VisualStateGroup>
                                </VisualStateManager.VisualStateGroups>
                                <ContentPresenter />
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
    

    Note that only one visual group can apply at a time and the last one wins.

    There are subtleties to this.

    See the line

     <VisualState x:Name="Normal"/>
    

    Remove that and see what happens