DataGrid's selected row color when inactive

WpfWpfdatagrid

Wpf Problem Overview


How can I style WPF DataGrid to change the color of selected row when DataGrid lost its focus?

Wpf Solutions


Solution 1 - Wpf

After ages of searching, I found a surprisingly simple way to do this that's cleaner than the Got/LostFocus approach posted earlier:

<DataGrid.Resources>
    <SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="DarkGray"/>
</DataGrid.Resources>

This just sets the inactive background colour to DarkGray, leaving the active background colour to the default, but you can change that too using the SystemColors.HighlightBrushKey too of course.

The foreground resource key for inactive selections is SystemColors.InactiveSelectionHighlightTextBrushKey.

Solution 2 - Wpf

Complete solution that works for 4.0. Note that this on the CellStyle.

<DataGrid.CellStyle>
    <!--Override Highlighting so that its easy to see what is selected even when the control is not focused-->
    <Style TargetType="{x:Type DataGridCell}">
        <Style.Triggers>
            <Trigger  Property="IsSelected" Value="true">
                <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" />
                <Setter Property="BorderBrush" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
            </Trigger>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsSelected}" Value="True" />
                    <Condition Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}, Path=IsKeyboardFocusWithin}" Value="False" />
                </MultiDataTrigger.Conditions>
                <MultiDataTrigger.Setters>
                    <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
                    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" />
                    <Setter Property="BorderBrush" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
                </MultiDataTrigger.Setters>
            </MultiDataTrigger>
        </Style.Triggers>
    </Style>
</DataGrid.CellStyle>

Solution 3 - Wpf

Do it like this:

<DataGrid ...>
    <DataGrid.Resources> 
        <Style TargetType="DataGridRow"> 
            <Style.Resources> 
                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Red"/>                                  
            </Style.Resources> 
        </Style> 
   </DataGrid.Resources> 
...

Solution 4 - Wpf

None of these answers gave me quite what I was looking for. The top rated by Steve Streeting changed other sections of the datagrid that I didn't want to change, and other answers weren't providing the inactive color change, but were properly targeting the row only. So here's a mixture of their answers that changes the inactive color, only on the rows and not in other places on the grid.

<DataGrid.Resources>
	<Style TargetType="DataGridRow">
		<Style.Resources>
			<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="DarkGray"/>
		</Style.Resources>
	</Style>
</DataGrid.Resources>

Solution 5 - Wpf

LATE ANSWER:

This works in .Net 4.0, and you don't have to hardcode the color:

<Style TargetType="DataGridRow">
    <Style.Resources>
         <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="{x:Static SystemColors.HighlightColor}" />
         <SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="{x:Static SystemColors.HighlightTextColor}"/>
    </Style.Resources>
</Style>

Solution 6 - Wpf

For .Net Framework 4.0 (or if you don't want to use the InactiveSelection... brush keys): Create a DataGridRow style/control template, and add these triggers:

<ControlTemplate.Triggers>
    <Trigger  Property="IsSelected" Value="true">
        <Setter Property="Background" Value="{DynamicResource SelectionBrush}" />
    </Trigger>
    <MultiDataTrigger>
        <MultiDataTrigger.Conditions>
            <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsSelected}" Value="True" />
            <Condition Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}, Path=IsKeyboardFocusWithin}" Value="False" />
        </MultiDataTrigger.Conditions>
        <MultiDataTrigger.Setters>
            <Setter Property="Background" Value="{DynamicResource InactiveSelectionBrush}" />
        </MultiDataTrigger.Setters>
    </MultiDataTrigger>
</ControlTemplate.Triggers>

Solution 7 - Wpf

I added this to my ResourceDictionary so that it applies to all data grids in my program.

<Style TargetType="DataGrid">
    <Style.Resources>
        <SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="LightGray"/>
    </Style.Resources>        
</Style>

Solution 8 - Wpf

You should define section "DataGrid.CellStyle" inside your DataGrid like this:

    <DataGrid>
        <DataGrid.CellStyle>
            <Style TargetType="DataGridCell">
                <Style.Triggers>
                    <Trigger Property="IsSelected" Value="True">
                        <Setter Property="Background" Value="LightBlue"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </DataGrid.CellStyle>
    </DataGrid>

Solution 9 - Wpf

Find an answer by myself.

Add to DataGrid's resources the brush, which can change its 'Color' property from code behind, and reference HighlightBrushKey to it:

<DataGrid.Resources>
	<SolidColorBrush x:Key="SelectionColorKey" Color="DarkGray"/>
	<Style TargetType="DataGridRow">
		<Style.Resources>
			<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="{Binding Source={StaticResource SelectionColorKey}, Path=Color}"/>
		</Style.Resources>
	</Style>
</DataGrid.Resources>

Then add DataGrids event handlers to manually change the color:

private void DataGrid1_LostFocus(object sender, RoutedEventArgs e)
{
	((SolidColorBrush)DataGrid1.Resources["SelectionColorKey"]).Color = Colors.DarkGray;
}

private void DataGrid1_GotFocus(object sender, RoutedEventArgs e)
{
	((SolidColorBrush)DataGrid1.Resources["SelectionColorKey"]).Color = SystemColors.HighlightColor;
}

private void DataGrid1_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
	((SolidColorBrush)DataGrid1.Resources["SelectionColorKey"]).Color = Colors.DarkGray;
}

Solution 10 - Wpf

For .net Framework 4.0

<Style TargetType="DataGridRow">
 <Style.Resources>
     <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="DarkGray" />
     <SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="White"/>
 </Style.Resources>
</Style>

https://social.msdn.microsoft.com/Forums/vstudio/en-US/635642e6-4808-4b3e-8aea-c8c434397d0f/datagrid-lost-focus-brush?forum=wpf

Solution 11 - Wpf

For .NET 4.0 or higher: It is also possible to set the colors programmatically:

if (TestDataGrid.RowStyle == null)
{
  TestDataGrid.RowStyle = new Style(typeof(DataGridRow));
}
    
// Set colors for the selected rows if focus is inactive
TestDataGrid.RowStyle.Resources.Add(SystemColors.ControlBrushKey, new SolidColorBrush(Colors.SkyBlue));
TestDataGrid.RowStyle.Resources.Add(SystemColors.ControlTextBrushKey, new SolidColorBrush(Colors.Black));
  
// Set colors for the selected rows if focus is active
TestDataGrid.RowStyle.Resources.Add(SystemColors.HighlightBrushKey, new SolidColorBrush(Colors.Red));
TestDataGrid.RowStyle.Resources.Add(SystemColors.HighlightTextBrushKey, new SolidColorBrush(Colors.White));

For .NET 4.5 or higher there is the following alternative to set the colors programmatically:

if (TestDataGrid.Resources == null)
{
  TestDataGrid.Resources = new ResourceDictionary();
}

// Set colors for the selected rows if focus is inactive
TestDataGrid.Resources.Add(SystemColors.InactiveSelectionHighlightBrushKey, new SolidColorBrush(Colors.SkyBlue));
TestDataGrid.Resources.Add(SystemColors.InactiveSelectionHighlightTextBrushKey, new SolidColorBrush(Colors.Black));

// Set colors for the selected rows if focus is active
TestDataGrid.Resources.Add(SystemColors.HighlightBrushKey, new SolidColorBrush(Colors.Red));
TestDataGrid.Resources.Add(SystemColors.HighlightTextBrushKey, new SolidColorBrush(Colors.White));

Solution 12 - Wpf

I had a similar problem. The scenario was a DataGrid with colors assigned for: RowBackground and AlternatingRowBackground. When the DataGrid Lose Focus, the selected row became Gray, returning to the correct color when the DataGrid regained Focus by clicking on any row. This effect was unpleasant. I started from the solution proposed here by Steve Streeting:

<Style TargetType="DataGrid">
	<Style.Resources>
		<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" 
                         Color="LightGray"/>
	</Style.Resources>
</Style>

but by changing Color = "Transparent".

<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" 
                 Color="Transparent"/>

this solved the problem in a simple and satisfactory way. valid for .net 4.5, not for .net 4.0.

Hope this solution is useful

incorrect behavior:

incorrect behavior

correct behavior:

correct behavior

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionwhite.zazView Question on Stackoverflow
Solution 1 - WpfSteve StreetingView Answer on Stackoverflow
Solution 2 - WpfBigSandwichView Answer on Stackoverflow
Solution 3 - WpfHCLView Answer on Stackoverflow
Solution 4 - WpfDLehView Answer on Stackoverflow
Solution 5 - WpfEren ErsönmezView Answer on Stackoverflow
Solution 6 - WpfCainKellyeView Answer on Stackoverflow
Solution 7 - WpfRahbekView Answer on Stackoverflow
Solution 8 - WpfLulchenko AlekseyView Answer on Stackoverflow
Solution 9 - Wpfwhite.zazView Answer on Stackoverflow
Solution 10 - WpfmicharazeView Answer on Stackoverflow
Solution 11 - WpfHans-Peter KalbView Answer on Stackoverflow
Solution 12 - WpfMassimo PravatoView Answer on Stackoverflow