How to disable row selection in a WPF DataGrid?

Disabling row selection in the WPF DataGrid included in .NET Framework 4 is not really easy. It is extremely difficult to do, unless you have the right tools and know exactly how to do it.

But all the difficulty is in figuring out how to do it. Once you know how to do it, the steps are quite easy to perform.

First, you basically have to use a copy of the default DataGrid style.  However, the easiest way to get a copy of the default DataGrid style is using Expression Blend.

Step 1 – Create a copy of the DataGrid’s default style

I used Expression Blend and .NET 4 to do this first step. Visual Studio 2010 doesn’t have this feature.  However, you don’t need Expression Blend because you can just copy the default style right here from this post.

(This step is a replica of the steps I posted earlier here:
How to create a copy of a control’s default style?)

  1. Open Expression Blend.
  2. Create a new WPF project. (I just used a temp project as I am coding in Visual Studio.)
  3. Add a DataGrid to your MainWindow.xaml.
  4. Right-click on the DataGrid and choose Edit Template | Edit a Copy.
  5. On the Create Style Resource page, click the “New…” button near the bottom right, just to the right of the Resource dictionary option.
  6. In the New Item window, provide a name, such as ResourceDictionaryDataGridSelectDisabled.xaml.
  7. Click OK to create the file and to return the Create Style Resource page.
  8. Make sure Resource dictionary is selected (it should be) and click OK.

You have now created a copy of the DataGrid’s default style as a Resource Dictionary file.

Note: Now that you have the DataGrid’s default style in a file, you can copy it to the project you are really working on.  I am not going to walk you through this.

Step 2 – Edit the DataGrid Style

On line 66, there is an ItemsPresenter object.  Set IsHitTestVisible="False" on this line as shown below. This is the only edit I have done.

Note: Notice I did not add an x:Key so that it will become the default style for any object that has access to this resource dictionary.

<ResourceDictionary
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	>
	<Style TargetType="{x:Type DataGrid}">
		<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
		<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
		<Setter Property="BorderBrush" Value="#FF688CAF"/>
		<Setter Property="BorderThickness" Value="1"/>
		<Setter Property="RowDetailsVisibilityMode" Value="VisibleWhenSelected"/>
		<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
		<Setter Property="ScrollViewer.PanningMode" Value="Both"/>
		<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
		<Setter Property="Template">
			<Setter.Value>
				<ControlTemplate TargetType="{x:Type DataGrid}">
					<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"
						Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="True">
						<ScrollViewer x:Name="DG_ScrollViewer" Focusable="false">
							<ScrollViewer.Template>
								<ControlTemplate TargetType="{x:Type ScrollViewer}">
									<Grid>
										<Grid.ColumnDefinitions>
											<ColumnDefinition Width="Auto"/>
											<ColumnDefinition Width="*"/>
											<ColumnDefinition Width="Auto"/>
										</Grid.ColumnDefinitions>
										<Grid.RowDefinitions>
											<RowDefinition Height="Auto"/>
											<RowDefinition Height="*"/>
											<RowDefinition Height="Auto"/>
										</Grid.RowDefinitions>
										<Button Command="{x:Static DataGrid.SelectAllCommand}" Focusable="false"
											Style="{DynamicResource {ComponentResourceKey ResourceId=DataGridSelectAllButtonStyle,
													TypeInTargetAssembly={x:Type DataGrid}}}"
											Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.All},
														 Converter={x:Static DataGrid.HeadersVisibilityConverter},
														 RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
											Width="{Binding CellsPanelHorizontalOffset,
													RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
										<DataGridColumnHeadersPresenter x:Name="PART_ColumnHeadersPresenter" Grid.Column="1"
											Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.Column},
														 Converter={x:Static DataGrid.HeadersVisibilityConverter},
														 RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
										<ScrollContentPresenter x:Name="PART_ScrollContentPresenter"
											CanContentScroll="{TemplateBinding CanContentScroll}" Grid.ColumnSpan="2" Grid.Row="1"/>
										<ScrollBar x:Name="PART_VerticalScrollBar" Grid.Column="2" Maximum="{TemplateBinding ScrollableHeight}"
											Orientation="Vertical" Grid.Row="1"
											Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"
											Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"
											ViewportSize="{TemplateBinding ViewportHeight}"/>
										<Grid Grid.Column="1" Grid.Row="2">
											<Grid.ColumnDefinitions>
												<ColumnDefinition Width="{Binding NonFrozenColumnsViewportHorizontalOffset,
																 RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
												<ColumnDefinition Width="*"/>
											</Grid.ColumnDefinitions>
											<ScrollBar x:Name="PART_HorizontalScrollBar" Grid.Column="1" Maximum="{TemplateBinding ScrollableWidth}"
												Orientation="Horizontal" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"
												Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"
												ViewportSize="{TemplateBinding ViewportWidth}"/>
										</Grid>
									</Grid>
								</ControlTemplate>
							</ScrollViewer.Template>
							<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" IsHitTestVisible="False"/>
						</ScrollViewer>
					</Border>
				</ControlTemplate>
			</Setter.Value>
		</Setter>
		<Style.Triggers>
			<Trigger Property="IsGrouping" Value="true">
				<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
			</Trigger>
		</Style.Triggers>
	</Style>
	<!-- Resource dictionary entries should be defined here. -->
</ResourceDictionary>

Step 3 – Configure the DataGrid to use the new style

Now that you have your new style in a resource dictionary (and I assume you have already added the file you created in Step 1 to your project), you can add the ResourceDictionary to the DataGrid’s object under DataGrid.Resources as shown.

<DataGrid ... />
    <DataGrid.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="ResourceDictionaryDataGridSelectDisabled.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </DataGrid.Resources>
</DataGrid>

I hope this helps you have some more success with a DataGrid from day one as it took me some time to get this working.

4 Comments

  1. Mike says:

    I think that Chinese guy is trying to tell us why on earth we don’t have a property like RowSelection=”Disabled”, and why do we have to write an A4 long XAML code to accomplish that.

  2. Hyb says:

    Hi,
    this way the row is not selectable (like it’s disabled)…ok…but I can’t
    click on hyperlinks column too. Clicking them won’t work.

    • Rhyous says:

      You are so correct, shame on me for not putting that in here when I ran into that as well.

      I tried to figure out a solution for that but ran into dead ends trying.

      I had some serious issues with the DataGrid (including one bug I submitted) and we changed to a ListView as the features we needed allowed that. The other option was to try to use the Telerik DataGrid, but since I got this working with a ListView, we didn’t pursue Telerik’s DataGrid.

      However, I know there is this looming missing feature that I don’t have a solution for yet.

  3. […] How to disable row selection in a WPF DataGrid? Share this:ShareFacebookStumbleUponDiggEmailReddit Category: C# (C-Sharp), Expression Blend, Visual Studio, WPF  |  Comment (RSS)  |  Trackback […]

Leave a Reply