Wpf – How to set a WPF ListView Selected Item color

background-colorlistviewlistviewitemstyleswpf

I am trying to recreate the Mail UI from Windows 8 in a WPF application running on Windows 7. Here's what I want to achieve:

Target UI

In particular, I don't know how to change the background color for selected items e.g. the Inbox item in the first column and the mail from Twitter in the second column. I have tried several solutions from other similar Stackoverflow Questions but none seem to work for me. e.g.

Selected item loses style when focus moved out in WPF ListBox

WPF ListView Inactive Selection Color

Here is the code I have for my listview:

<ListView Grid.Row="0" SelectedItem="{Binding Path=SelectedArea}" ItemsSource="{Binding Path=Areas}" Background="#DCE3E5" >

                    <ListView.Resources>

                        <!-- Template that is used upon selection of an Area -->
                        <ControlTemplate x:Key="SelectedTemplate" TargetType="ListViewItem">
                            <Border Background="#388095" Cursor="Hand" >
                                <TextBlock Text="{Binding Name}" Margin="5" />
                            </Border>                                
                        </ControlTemplate>

                        <Style TargetType="ListViewItem">
                            <Setter Property="Template">
                                <Setter.Value>                                        
                                    <!-- Base Template that is replaced upon selection -->
                                    <ControlTemplate TargetType="ListViewItem">
                                        <Border Background="#DCE3E5" Cursor="Hand"  >
                                            <TextBlock Text="{Binding Name}" Margin="5" />
                                        </Border>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                            <Style.Triggers>
                                <MultiTrigger>
                                    <MultiTrigger.Conditions>
                                        <Condition Property="IsSelected" Value="true" />
                                    </MultiTrigger.Conditions>
                                    <Setter Property="Template" Value="{StaticResource SelectedTemplate}" />
                                </MultiTrigger>
                            </Style.Triggers>
                        </Style>

                    </ListView.Resources>                        

                </ListView>

How can I change the background color of the selected item? And how do I retain the color change when the focus changes.

Best Answer

I did something similar to this recently:

<ListView.Resources>                
    <ControlTemplate x:Key="SelectedTemplate" TargetType="ListViewItem">
        <Border CornerRadius="5" BorderThickness="1" BorderBrush="DarkGray" Background="#FF92C6F9" Padding="2" HorizontalAlignment="Left" Margin="5" Tag="{Binding Value}" Cursor="Hand" MouseUp="Border_MouseUp_1">                        
            <TextBlock Text="{Binding Name}" Margin="5" />
        </Border>
    </ControlTemplate>
    <Style TargetType="ListViewItem">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListViewItem">
                    <Border CornerRadius="5" BorderThickness="1" BorderBrush="DarkGray" Background="WhiteSmoke" Padding="2" HorizontalAlignment="Left" Margin="5" Tag="{Binding Value}" Cursor="Hand" MouseUp="Border_MouseUp_1" >                                    
                        <TextBlock Text="{Binding Name}" Margin="5" />
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <MultiTrigger>
                <MultiTrigger.Conditions>
                    <Condition Property="IsSelected" Value="true" />
                    <Condition Property="Selector.IsSelectionActive" Value="true" />
                </MultiTrigger.Conditions>                            
                <Setter Property="Template" Value="{StaticResource SelectedTemplate}" />                            
            </MultiTrigger>
        </Style.Triggers>
    </Style>
</ListView.Resources>

I believe removing:

<Condition Property="Selector.IsSelectionActive" Value="true" />

will allow you to keep the background color after focus is lost.

EDIT:

In response to your question below:

You can bind the tag property of the TextBlock to the command parameter, and then execute the command on the MouseUp event of the TextBlock:

<TextBlock x:Name="MyTextBlock" Text="Click Me!" Tag="{Binding MyCommandParameter}" MouseUp="MyTextBlock_MouseUp" />

And in the code behind:

    private void MyTextBlock_MouseUp(object sender, MouseButtonEventArgs e)
    {
        TextBlock tb = sender as TextBlock;

        if (tb != null && tb.Tag != null)
        {
            ViewModel.MyCommand.Execute(tb.Tag);
        }            
    }