Search code examples
wpfxamldatagrid

How to show always the blue color of a selected row, no matter if it has the focus or not?


I am trying to show always the blue color of the row of a DataGrid, no matter if it has the focus or not. I am trying this code:

<DataGrid.RowStyle>
    <Style TargetType="DataGridRow">
        <Style.Triggers>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding Path=IsSelected}" Value="true"/>
                </MultiDataTrigger.Conditions>
                <MultiDataTrigger.Setters>
                    <Setter Property="Background" Value="{x:Static SystemColors.HighlightBrushKey}" />
                </MultiDataTrigger.Setters>
            </MultiDataTrigger>
        </Style.Triggers>
    </Style>
</DataGrid.RowStyle>

But I get the error that SystemResourcesKey is not valid, it is only possible to use BindingBase elements.

How can I set the default blue color of the row when the row is selected?


Solution

  • There are a few reasons why your current approach does not work:

    • You refer to the Key of the property, not the brush HighlightBrush
    • You have to bind the IsSelected property on the DataGridRow itself using RelativeSource
    • The row background is occluded by each cell that has background on its own

    In order to make it work, replace the key by the brush, adapt the binding to IsSelected and add a cell style that sets the background of the individual cells to the desired background. Alternatively, you could set the cell background to Transparent, so the row background is not occluded.

    Please note, that I also added setters to adapt the Foreground and BorderBrush, too, so that it looks the same as in selected state. However, I recommend you to not use the BorderBrush, since the border color is also used in validation and other visual states.

    <DataGrid.CellStyle>
       <Style TargetType="{x:Type DataGridCell}">
          <Style.Triggers>
             <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                   <Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}}" Value="True" />
                </MultiDataTrigger.Conditions>
                <MultiDataTrigger.Setters>
                   <Setter Property="Background" Value="{x:Static SystemColors.HighlightBrush}" />
                   <Setter Property="Foreground" Value="{x:Static SystemColors.HighlightTextBrush}" />
                   <Setter Property="BorderBrush" Value="{x:Static SystemColors.HighlightBrush}"/>
                </MultiDataTrigger.Setters>
             </MultiDataTrigger>
          </Style.Triggers>
       </Style>
    </DataGrid.CellStyle>
    
    <DataGrid.RowStyle>
       <Style TargetType="{x:Type DataGridRow}">
          <Style.Triggers>
             <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                   <Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="true" />
                </MultiDataTrigger.Conditions>
                <MultiDataTrigger.Setters>
                   <Setter Property="Background" Value="{x:Static SystemColors.HighlightBrush}" />
                </MultiDataTrigger.Setters>
             </MultiDataTrigger>
          </Style.Triggers>
       </Style>
    </DataGrid.RowStyle>
    

    If you do not care about the background of the cells that do not belong to any column (that take up the remaining space to the right) you do not need the row style at all.