Search code examples
c#wpfdatagridwpf-style

DataGrid RowStyle not working for IsSelected and IsMouseOver combination


I have a simple DatGrid. I want to set the background color of my rows accordingly to specific criteria. In this example the row is just red at the beginning.

I want to change that basic background color to different colors

  • when the mouse hovers over the row
  • when the row is selected
  • when the row is selected and the mouse hovers over it

The thing is that it works for the cells but not for the complete row.

I set a MultiTrigger for the last requirement and it changes the cell color but not the color of the complete row. When I move the CellStyle MultiTrigger to RowStyle it does not do anything anymore.

screenshot

<Window x:Class="MyWindow"
        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:WpfTest" >
    <Window.DataContext>
        <local:MyWindowViewModel />
    </Window.DataContext>
    <Grid>
        <DataGrid ItemsSource="{Binding Items}"
                  AutoGenerateColumns="False" 
                  SelectionMode="Single" SelectionUnit="FullRow" >    
            <DataGrid.RowStyle>
                <Style TargetType="DataGridRow">
                    <Setter Property="Background" Value="Red"/>

                    <Style.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Background" Value="Green" />
                        </Trigger>                                                  
                    </Style.Triggers>
                </Style>
            </DataGrid.RowStyle>

            <DataGrid.CellStyle>
                <Style TargetType="DataGridCell">
                    <Style.Triggers>
                        <Trigger Property="IsSelected" Value="True">
                            <Setter Property="Background" Value="Orange" />
                        </Trigger>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="IsSelected" Value="True" />
                                <Condition Property="IsMouseOver" Value="True" />
                            </MultiTrigger.Conditions>
                            <Setter Property="Background" Value="Yellow"/>
                        </MultiTrigger>
                    </Style.Triggers>
                </Style>
            </DataGrid.CellStyle>

            <DataGrid.Columns>
                <DataGridTextColumn Header="FirstName"  Width="50*" Binding="{Binding FirstName}" />
                <DataGridTextColumn Header="LastName"  Width="50*" Binding="{Binding LastName}" />
            </DataGrid.Columns>            
        </DataGrid>
    </Grid>
</Window>

Model / ViewModel:

class Model
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

class MyWindowViewModel
{
    public List<Model> Items { get; private set; }

    public MyWindowViewModel()
    {
        Items = new List<Model>();
        Items.Add(new Model { FirstName = "AB", LastName = "CD"});
        Items.Add(new Model { FirstName = "EF", LastName = "GH" });
        Items.Add(new Model { FirstName = "IJ", LastName = "KL" });
    }
}

Solution

  • You need a DataTrigger on your DataGridCell style that will bind to parent rows IsSelected so all cells change the style rather than just the one you are hovering.

    <DataTrigger Binding="{Binding Path=IsMouseOver, RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}}" Value="True">
        <Setter Property="Background" Value="Yellow"/>
    </DataTrigger>