Wednesday, July 23, 2014

Bug when styling DatagridCheckBoxColumn

There is a bug in WPF 4.0 that breaks the IsReadOnly property of the DataGridCheckBoxColumn when it is styled. To see the problem, create a new WPF project with the following XAML and code behind.
<Window x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525" DataContext="{Binding RelativeSource={RelativeSource Self}}"> <Window.Resources> <Style x:Key="CheckBox" TargetType="{x:Type CheckBox}"> <Setter Property="Background" Value="Aqua"/> </Style> </Window.Resources> <StackPanel Orientation="Vertical"> <CheckBox Name="DisableGridCheckBox" Content="Disable Grid"/> <DataGrid Name="DataGrid" AutoGenerateColumns="False" ItemsSource="{Binding DataSource}" IsReadOnly="{Binding ElementName=DisableGridCheckBox, Path=IsChecked}"> <DataGrid.Columns> <DataGridTextColumn x:Name="TextColumn" Header="Text" Binding="{Binding TextField}"/> <DataGridCheckBoxColumn x:Name="UnstyledCheckboxColumn" Header="Unstyled" Binding="{Binding CheckBox1}"/> <DataGridCheckBoxColumn x:Name="StyledCheckboxColumn" Header="Styled" Binding="{Binding CheckBox2}" ElementStyle="{StaticResource CheckBox}"/> </DataGrid.Columns> </DataGrid> </StackPanel> </Window> --------------------------------------------------------------------------- Imports System.Data Class MainWindow Public Property DataSource As New DataTable Public Sub New() DataSource.Columns.Add(New DataColumn("TextField", GetType(String))) DataSource.Columns.Add(New DataColumn("CheckBox1", GetType(Boolean))) DataSource.Columns.Add(New DataColumn("CheckBox2", GetType(Boolean))) DataSource.Rows.Add("Text", True, False) InitializeComponent() End Sub End Class
When you run this project you will see an editable grid with a text box, an unstyled checkbox and a styled checkbox (with a pretty aqua background). Modify the text and check the checkboxes to verify that they have inherited the grid's IsReadOnly property.

Now check the top checkbox labeled "Disable Grid". This will put the grid into ReadOnly mode. Verify you cannot change the text or check the unstyled checkbox. However you can still check the styled checkbox. This is a bug.

Styling the checkbox has broken the IsHitTestVisible property (and others too, such as the Horizontal Alignment). To fix this, you need to alter the style to bind the IsHitTestVisible property to the parent datagrid's IsReadOnly property. The easiest way to do this is with a DataTrigger. Add the following to the style. Note that when the parent DataGrid.IsReadOnly is true we want the Checkbox.IsHitTestVisible to be false.

<Setter Property="IsHitTestVisible" Value="True"/> <Style.Triggers> <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=DataGrid}, Path=IsReadOnly}" Value="True"> <Setter Property="IsHitTestVisible" Value="False"/> </DataTrigger> </Style.Triggers>

No comments:

Post a Comment