47
votes

I am seeing a lot of examples on how to style Selected rows in DataGrid such as this one:

How can I set the color of a selected row in DataGrid

Can i just disabled selected row styling? i don't want to have to override every single thing that selected row changes. Just don't want any visible changes. Gotta be easier way than to create templates..

or..

disable selecting rows, if that is easier.. but from browsing this forum that seems hacky as well

Disable selecting in WPF DataGrid

7

7 Answers

81
votes

figured out the XAML to get rid of selection style.. not ideal, but close enough..

<Style x:Key="CellStyle" TargetType="{x:Type DataGridCell}">
    <Setter Property="Foreground" Value="Black" />
    <Style.Triggers>
        <Trigger Property="IsSelected" Value="True">
            <Setter Property="Background" Value="{x:Null}" />
            <Setter Property="BorderBrush" Value="{x:Null}" />
        </Trigger>
    </Style.Triggers>
</Style>
26
votes

Here's what worked for me:

<DataGrid>
    <DataGrid.CellStyle>
        <Style TargetType="{x:Type DataGridCell}">
            <Style.Triggers>
                <Trigger Property="DataGridCell.IsSelected" Value="True">
                    <Setter Property="BorderBrush">
                        <Setter.Value>
                            <SolidColorBrush Color="Transparent"/>
                        </Setter.Value>
                    </Setter>
                    <Setter Property="Foreground"
                            Value="{DynamicResource
                                   {x:Static SystemColors.ControlTextBrushKey}}"/>
                    <Setter Property="Background">
                        <Setter.Value>
                            <SolidColorBrush Color="Transparent"/>
                        </Setter.Value>
                    </Setter>
                </Trigger>
            </Style.Triggers>
        </Style>
    </DataGrid.CellStyle>
    <!-- ... -->
</DataGrid>
20
votes

I found another way that works well for my situation. I set this style for all cells because I don't want the user to select any cells.

<Style TargetType="{x:Type DataGridCell}">
    <Setter Property="IsHitTestVisible" Value="False"/>
</Style>
9
votes

I'll answer the second question first: to disable selection of rows, you could change the RowStyle of your DataGrid.

<DataGrid>
    <DataGrid.RowStyle>
        <Style TargetType="DataGridRow">
            <Setter Property="IsEnabled" Value="False"/>
        </Style>
    </DataGrid.RowStyle>
    <!--Other DataGrid items-->
</DataGrid>

However, this changes the text style as the row itself is now "disabled". It also doesn't negate the fact that a user can still right click on the row to select it. If you really wanted to disable any kind of interaction with the datagrid's rows, you could do the following:

<DataGrid>
    <DataGrid.RowStyle>
        <Style TargetType="DataGridRow">
            <Setter Property="IsHitTestVisible" Value="False"/>
        </Style>
    </DataGrid.RowStyle>
    <!--Other DataGrid items-->
</DataGrid>

As the rows are still enabled, the style of the text does not change.

Now if you wanted to only change the style of selected row but leave the functionality alone, you could do the following (which is basically the same as @Dan Stevens' answer). The ControlTextBrushKey is the brush that is used by the system to color text items. Please look at this answer for an explanation between DynamicResource and StaticResource.

<DataGrid>
    <DataGrid.CellStyle>
        <Style TargetType="{x:Type DataGridCell}">
            <Style.Triggers>
                <Trigger Property="DataGridCell.IsSelected" Value="True">
                    <Setter Property="BorderBrush" Value="Transparent"/>
                    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
                    <Setter Property="Background" Value="Transparent"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </DataGrid.CellStyle>
    <!--Other DataGrid items-->
</DataGrid>

It is important to note that the above solution does not change the style of DataGridRowHeader when the row is selected, as can be seen below (the first row is selected).

enter image description here

6
votes

This is relatively straightforward:

datagrid.SelectionChanged += (obj, e) =>
  Dispatcher.BeginInvoke(DispatcherPriority.Render, new Action(() =>
    datagrid.UnselectAll()));

This disables all selection on the DataGrid.

If you don't want to disable selection entirely but just hide it you'll need to modify the template.

1
votes

For those like me who have some cells with different styles and don't want to override all styles nor add triggers to each style, this is a good bet:

<DataGrid.Resources>
    <SolidColorBrush 
        x:Key="{x:Static SystemColors.HighlightBrushKey}" 
        Color="#333333"/>
    <SolidColorBrush 
        x:Key="{x:Static SystemColors.HighlightTextBrushKey}" 
        Color="Black"/>
    <SolidColorBrush 
        x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" 
        Color="Black"/>
    <SolidColorBrush 
        x:Key="{x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}" 
        Color="Black"/>
</DataGrid.Resources>

HighlightBrushKey is the highlighted border with active selection and HighlightTextBrushKey is the text color with active selection

In my case, I want inactive selection to look unselected:

InactiveSelectionHighlightBrushKey is the border when selection is inactive and InactiveSelectionHighlightTextBrushKey is the text when selection is inactive

FYI: SystemColors is a static class, part of System.Windows.Media namespace. You can inspect it and shamelessly override any color you don't like!

1
votes
<Style TargetType="DataGridCell">
    <Style.Triggers>
        <Trigger Property="DataGridCell.IsSelected" Value="True">
            <Setter Property="BorderBrush" Value="Transparent"/> <!--Removes brush color change-->
            <Setter Property="Foreground" Value="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Foreground}"/> <!--Removes foregound change-->
            <Setter Property="Background" Value="Transparent"/>  <!--Removes backgound change-->
        </Trigger>
    </Style.Triggers>
    <Setter Property="FocusVisualStyle" Value="{x:Null}"/> <!--Removes dotted border when on cell selection change made by keyboard-->
</Style>

I have slightly modified Dan Stevens and JoshuaTheMiller's solutions. Use this solution if:

  • you have cells with different foreground color you should use this one approach not to reset color to SystemColors.ControlTextBrushKey but to preserve it unchanged
  • you want to disable cell (and row) selection made by mouse and keyboard