Disable selecting in WPF DataGrid

C#WpfDatagridFocusSelection

C# Problem Overview


How can I disable selecting in a WPFTooklit's DataGrid? I tried modifying the solution that works for ListView (from https://stackoverflow.com/questions/1051215/wpf-listview-turn-off-selection#comment-863179), but that doesn't work:

<tk:DataGrid>
	<tk:DataGrid.ItemContainerStyle>
		<Style TargetType="{x:Type tk:DataGridRow}">
			<Setter Property="Focusable" Value="false"/>
		</Style>
	</tk:DataGrid.ItemContainerStyle>
	<tk:DataGrid.CellStyle>
		<Style TargetType="{x:Type tk:DataGridCell}">
			<Setter Property="Focusable" Value="false"/>
		</Style>
	</tk:DataGrid.CellStyle>
</tk:DataGrid>

C# Solutions


Solution 1 - C#

The clean way would be, to just override the styles of the row and the cell

<DataGrid.Resources>
    <ResourceDictionary>
        <Style x:Key="{x:Type DataGridCell}" TargetType="{x:Type DataGridCell}">
            <Setter Property="Background" Value="{x:Null}" />
            <Setter Property="BorderBrush" Value="{x:Null}" />
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="Background" Value="{x:Null}" />
                    <Setter Property="BorderBrush" Value="{x:Null}" />
                </Trigger>
            </Style.Triggers>
        </Style>
        <Style TargetType="{x:Type DataGridRow}">
            <Setter Property="Background" Value="{x:Null}" />
            <Setter Property="BorderBrush" Value="{x:Null}" />
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="Background" Value="{x:Null}" />
                    <Setter Property="BorderBrush" Value="{x:Null}" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </ResourceDictionary>
</DataGrid.Resources>

Solution 2 - C#

To completely disable selection of rows in a DataGrid, you could do the following:

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

This could be considered more favorable than setting <Setter Property="IsEnabled" Value="False"/> due to the fact that doing the aforementioned technique causes the style of the row to change. It also does not disable context menus from appearing when right-clicking.

Lastly: it is important to note that setting "IsHitTestVisible" to "False" disables all interaction with the rows, including editing.

However, if all you want to do is change the styling of the row when selected, please view the answers here.

Solution 3 - C#

Simply add IsHitTestVisible="False" to DataGrid definition.

Solution 4 - C#

All of the above are good ideas for easy hacks. However, they aren't doing exactly what is asked. The other answers are telling us how to unselect something selected by the user or hide the fact that something was selected by the user.

However, I understand why these answers are given. It is not easy to provide the real solution.

The real solution is to prevent selection in the first place, which it is not straightforward but it is doable with a few easy steps.

Answer

  1. You have to copy the style in Expression Blend (or find a copy of the style somewhere).
  2. Change a single ItemPresenter setting. It was enough for me to set IsHitTestVisible="False" on the ItemPresenter.

If you need more details, or an in-depth walk-thru for doing this, see my blog post:

How to disable row selection in a WPF DataGrid?

Solution 5 - C#

As pointed out by Sonic Soul here, viky's solution doesn't actually work.

Here is actual working code to disable selection in a DataGrid:

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

Solution 6 - C#

The only proper way I found to do this is to disable IsHitTestVisible property on DataGridRowStyle.

Click events will still register despite the naming. Make sure you do not change this property on the whole DataGrid unless you also want to disable scrolling.

A clean way of doing this is through a new Style in your static resources (copying other setters as appropriate)

        <Style x:Key="DataGridUnselectableRowStyle" TargetType="{x:Type DataGridRow}">
            <Setter Property="IsHitTestVisible" Value="False"/>
        </Style>

and then binding it on your DataGrid

        <DataGrid
            RowStyle="{StaticResource DataGridUnselectableRowStyle}" >
            <!-- Contents -->
        </DataGrid>

Solution 7 - C#

Another simple way is to change the Selection Style with an IsSelected Trigger to Transparent.

Solution 8 - C#

In case you are using alternate colors:

<Style TargetType="{x:Type DataGrid}">
    <Setter Property="RowBackground" Value="#badeee"/>
    <Setter Property="AlternationCount" Value="2" />
    <Setter Property="AlternatingRowBackground" Value="#92cce5"/>
</Style>

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

<Style TargetType="{x:Type DataGridRow}">
    <Style.Triggers>
        <Trigger Property="ItemsControl.AlternationIndex" Value="0">
            <Setter Property="Background" Value="#badeee"></Setter>
            <Setter Property="BorderBrush" Value="#badeee"></Setter>
        </Trigger>
        <Trigger Property="ItemsControl.AlternationIndex" Value="1">
            <Setter Property="Background" Value="#92cce5"></Setter>
            <Setter Property="BorderBrush" Value="#92cce5"></Setter>
        </Trigger>
    </Style.Triggers>
</Style>

Solution 9 - C#

If someone else is facing same problem, they may find it helpful.

We had a requirement to disable few rows on datagrid, but at the same time allow ARROW key navigation on them. This is why we had to switch to 'IsHitTestVisible' instead of controlling 'IsEnabled' property. So we couldn't adopt to above solution of switching to 'IsEnable' property.

Here is how I ended up solving this issue. I created a new attached property (RowEnable) for DataGridRow. This attached property can be bind to a viewmodel property to control 'virtual' enable and disablement. I also created a new style for DataGridCell where I am setting 'IsHitTestVisible' to false based on the same viewmodel property. So, consider it like a row which mouse/keyboard can see, but can't see its cells/columns. This means now I can style the row based on new attached property (RowEnabled) to look disabled/enabled. At the same time, I can view tooltips for these rows which are virtually disabled.

Solution 10 - C#

<DataGrid isEnabled="False">
</DataGrid>

This is the simplest way to directly answer your question: disable selecting in WPF Datagrid.

Solution 11 - C#

I needed a code behind solution. This works for me:

controlGrid.SelectedCellsChanged += (sender, e) =>
	Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Render, new Action(() =>
		controlGrid.UnselectAll()));
controlGrid.Columns.Clear();

Because it sometimes flickers, the BackgroundProperty also be set to transparent.

Style dataGridCellStyle = new Style(typeof(DataGridCell));
Setter newSetterCell = new Setter(DataGridCell.BackgroundProperty, Brushes.Transparent);
dataGridCellStyle.Setters.Add(newSetterCell);
controlGrid.CellStyle = dataGridCellStyle;

Solution 12 - C#

There is a trick for this. You can handle SelectionChanged event of the DataGrid(say dgGrid) and in the handler write:

dgGrid.UnselectAll();

It will unselect all selected row and result will be "No row selected".

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
QuestionsvickView Question on Stackoverflow
Solution 1 - C#AlexView Answer on Stackoverflow
Solution 2 - C#JoshuaTheMillerView Answer on Stackoverflow
Solution 3 - C#ybondaView Answer on Stackoverflow
Solution 4 - C#RhyousView Answer on Stackoverflow
Solution 5 - C#Ray BurnsView Answer on Stackoverflow
Solution 6 - C#Mindaugas-kunView Answer on Stackoverflow
Solution 7 - C#Mr. SnugglesView Answer on Stackoverflow
Solution 8 - C#silver_mxView Answer on Stackoverflow
Solution 9 - C#Vipin GuptaView Answer on Stackoverflow
Solution 10 - C#Piano TelopeView Answer on Stackoverflow
Solution 11 - C#marsh-wiggleView Answer on Stackoverflow
Solution 12 - C#vikyView Answer on Stackoverflow