Bitsec Bitsec - 3 months ago 36
C# Question

How To Style Selected and MouseOver Items In A ListView

I'm trying to change the look of the ListView Item when its Selected and when its hovered over. I have tried answers from other questions which suggest to use Style.Trigger but somehow that doesn't work for me.
It currently looks like this:
Image of what it looks like now

Here is the code I use:

<UserControl x:Class="PROShine.TeamView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:PROShine"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<SolidColorBrush x:Key="NormalBorderBrush" Color="#FF111111" />
<SolidColorBrush x:Key="HeaderBackgroundColor" Color="#FF111111" />
<SolidColorBrush x:Key="HeaderBorderBrush" Color="#FF1e1e1e" />
<SolidColorBrush x:Key="NormalBrush" Color="#FF111111" />
<SolidColorBrush x:Key="PressedBrush" Color="#FF1e1e1e" />
<SolidColorBrush x:Key="SeperatorBrush" Color="#FF1e1e1e" />
<SolidColorBrush x:Key="ForegroundDefault" Color="White" />
<SolidColorBrush x:Key="SolidBorderBrush" Color="#FF111111" />
<SolidColorBrush x:Key="WindowBackgroundBrush" Color="#FF0d0d0d" />

<Style x:Key="GridViewColumnHeaderGripper" TargetType="Thumb">
<Setter Property="Width" Value="18"/>
<Setter Property="Background" Value="{StaticResource SeperatorBrush}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border Padding="{TemplateBinding Padding}" Background="Transparent">
<Rectangle HorizontalAlignment="Center" Width="1" Fill="{TemplateBinding Background}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

<Style x:Key="{x:Type GridViewColumnHeader}" TargetType="GridViewColumnHeader">
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Foreground" Value="{StaticResource ForegroundDefault}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GridViewColumnHeader">
<Grid>
<Border Name="HeaderBorder" BorderThickness="0,0,0,1" BorderBrush="{StaticResource HeaderBorderBrush}" Background="{StaticResource HeaderBackgroundColor}" Padding="2,0,2,0">
<ContentPresenter Name="HeaderContent" Margin="0,0,0,1" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
<Thumb x:Name="PART_HeaderGripper" HorizontalAlignment="Right" Margin="0,0,-9,0" Style="{StaticResource GridViewColumnHeaderGripper}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="HeaderBorder" Property="Background" Value="{StaticResource NormalBrush}"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="HeaderBorder" Property="Background" Value="{StaticResource PressedBrush}"/>
<Setter TargetName="HeaderContent" Property="Margin" Value="1,1,0,0"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="White"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Role" Value="Floating">
<Setter Property="Opacity" Value="0.7"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GridViewColumnHeader">
<Canvas Name="PART_FloatingHeaderCanvas">
<Rectangle Fill="#60000000" Width="{TemplateBinding ActualWidth}" Height="{TemplateBinding ActualHeight}"/>
</Canvas>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="Role" Value="Padding">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GridViewColumnHeader">
<Border Name="HeaderBorder" BorderThickness="0,1,0,1" BorderBrush="{StaticResource NormalBorderBrush}" Background="{StaticResource HeaderBackgroundColor}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>

<Style x:Key="{x:Type ListView}" TargetType="{x:Type ListView}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Foreground" Value="{StaticResource ForegroundDefault}" />

<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListView}">
<Border Name="Border" BorderThickness="1" BorderBrush="{StaticResource SolidBorderBrush}" Background="{StaticResource WindowBackgroundBrush}">
<ScrollViewer Style="{DynamicResource {x:Static GridView.GridViewScrollViewerStyleKey}}">
<ItemsPresenter />
</ScrollViewer>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="Border" Property="Background" Value="{StaticResource SolidBorderBrush}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

<Style x:Key="ListViewItem" TargetType="{x:Type ListViewItem}">
<Setter Property="Foreground" Value="{StaticResource ForegroundDefault}"/>
<Style.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Background" Value="#FF111111" />
</Trigger>
</Style.Triggers>
</Style>

</UserControl.Resources>
<Grid>
<ListView Name="PokemonsListView" PreviewMouseLeftButtonDown="List_PreviewMouseLeftButtonDown"
PreviewMouseMove="List_MouseMove"
Drop="List_Drop"
DragEnter="List_DragEnter"
AllowDrop="True" >
<ListView.View>
<GridView>
<GridViewColumn Header="Id" DisplayMemberBinding="{Binding Id}"/>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}"/>
<GridViewColumn Header="Level" DisplayMemberBinding="{Binding Experience.CurrentLevel}"/>
<GridViewColumn Header="Status" DisplayMemberBinding="{Binding Status}"/>
<GridViewColumn Header="HP" DisplayMemberBinding="{Binding Health}"/>
<GridViewColumn Header="Remaining Exp" DisplayMemberBinding="{Binding Experience.RemainingExperience}"/>
<GridViewColumn Header="Item" DisplayMemberBinding="{Binding ItemHeld}"/>
</GridView>
</ListView.View>
</ListView>
</Grid>
</UserControl>


Anyone can tell me what I do wrong?

Answer

Bind your style to ListView's ItemContainerStyle property as shown below:

XAML:

<Window
    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:WpfApplication266"
    xmlns:Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero2" 
    x:Class="WpfApplication266.MainWindow"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">

<Window.Resources>

    <Style x:Key="ListViewItemStyle1" TargetType="{x:Type ListViewItem}">
        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="true">
                <Setter Property="Background" Value="LightGreen" />
                <Setter Property="Foreground" Value="Blue" />
            </Trigger>
            <Trigger Property="IsSelected" Value="true">
                <Setter Property="Background" Value="LightCoral" />
                <Setter Property="Foreground" Value="White" />
            </Trigger>
        </Style.Triggers>
    </Style>

</Window.Resources>

<Window.DataContext>
    <local:MyViewModel/>
</Window.DataContext>

<Grid>
    <ListView x:Name="listView" Margin="0" 
              ItemsSource="{Binding Data}" 
              ItemContainerStyle="{StaticResource ListViewItemStyle1}">
        <ListView.View>
            <GridView>
                <GridViewColumn Header="ID" DisplayMemberBinding="{Binding ID}"/>
                <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}"/>
            </GridView>
        </ListView.View>
    </ListView>
</Grid>

ViewModel:

public class MyViewModel
{
    public ObservableCollection<MyData> Data { get; set; }

    public MyViewModel()
    {
        Data = new ObservableCollection<MyData>
        {
            new MyData {ID = 1, Name = "Name 1" },
            new MyData {ID = 2, Name = "Name 2" },
            new MyData {ID = 3, Name = "Name 3" },
            new MyData {ID = 4, Name = "Name 4" },
            new MyData {ID = 5, Name = "Name 5" },
        };
    }
}

enter image description here