Issue to preserve binding while styling a checkbox with a template

53 views Asked by At

I've an issue while styling a CheckBox. I was inspired by the original CheckBox style.

The problem is, I can't find a way to apply the original binding (into the property IsSelected). When I remove the style, the binding works. What should I add inside the ContentPresenter to preserve the CheckBox binding?

<DataGridCheckBoxColumn Binding="{Binding IsSelected}" ElementStyle="{StaticResource DataGridCheckBoxStyle}" MinWidth="6">
<Style x:Key="DataGridCheckBoxStyle" TargetType="{x:Type CheckBox}">
   <Setter Property="Template">
      <Setter.Value>
         <ControlTemplate TargetType="CheckBox">
            <BulletDecorator Background="Transparent">
               <BulletDecorator.Bullet>
                  <Border   x:Name="Border"  
                            Width="13" 
                            Height="13" 
                            CornerRadius="0" 
                            Background="White"
                            BorderThickness="1"
                            BorderBrush="{StaticResource Blue}">
                     <Path Width="8" Height="8" 
                           x:Name="CheckMark"
                           SnapsToDevicePixels="False" 
                           Stroke="White"
                           StrokeThickness="2"
                           Data="M 0 3.5 L 3.5 7 M 3.5 7 L 8 0" />
                  </Border>
               </BulletDecorator.Bullet>
               <ContentPresenter Margin="4,0,0,0"
                                 VerticalAlignment="Center"
                                 HorizontalAlignment="Left"
                                 RecognizesAccessKey="True"/>
            </BulletDecorator>
            <ControlTemplate.Triggers>
               <Trigger Property="IsChecked" Value="false">
                  <Setter TargetName="CheckMark" Property="Visibility" Value="Collapsed"/>
               </Trigger>
               <Trigger Property="IsChecked" Value="true">
                  <Setter TargetName="Border" Property="Background" Value="{StaticResource Blue}" />
               </Trigger>
               <Trigger Property="IsChecked" Value="{x:Null}">
                  <Setter TargetName="CheckMark" Property="Data" Value="M 0 7 L 7 0" />
               </Trigger>
               <Trigger Property="IsMouseOver" Value="true">
                  <!--<Setter TargetName="Border" Property="Background" Value="{StaticResource DarkGray}" />-->
               </Trigger>
               <Trigger Property="IsEnabled" Value="false">
                  <Setter TargetName="Border" Property="Background" Value="White" />
                  <Setter TargetName="Border" Property="BorderBrush" Value="{StaticResource LightGray}" />
                  <Setter Property="Foreground" Value="White"/>
               </Trigger>
            </ControlTemplate.Triggers>
         </ControlTemplate>
      </Setter.Value>
   </Setter>
</Style>
2

There are 2 answers

0
thatguy On

A data grid column always has two styles, the non-editable ElementStyle and the EditingElementStyle. You only create a style for the non-editable mode, where the CheckBox toggle state must not be changed.

Since your style allows the CheckBox to get focused and participate in hit testing, the edit mode is never entered and the changed toggle state is not applied to the IsSelected property.

In order to solve this issue, create a separate style for the non-editing mode based on your CheckBox style. This style prevents the toggle state to be changed and instead activates the edit mode.

<Style x:Key="DataGridCheckBoxElementStyle" TargetType="{x:Type CheckBox}" BasedOn="{StaticResource DataGridCheckBoxStyle}">
   <Setter Property="IsHitTestVisible" Value="False"/>
   <Setter Property="Focusable" Value="False"/>
</Style>

Apply both styles in your column as ElementStyle and EditingElementStyle.

<DataGridCheckBoxColumn Binding="{Binding IsSelected}"
                        ElementStyle="{StaticResource DataGridCheckBoxElementStyle}"
                        EditingElementStyle="{StaticResource DataGridCheckBoxStyle}"
                        MinWidth="6"/>
0
Simon Marsal On

Thanks for your answer, I already tested that,

I solved my problem just by adding UpdateSourceTrigger property :

<DataGridCheckBoxColumn Binding="{Binding IsSelected, UpdateSourceTrigger=PropertyChanged}" 
                        ElementStyle="{StaticResource DataGridCheckBoxStyle}" 
                        MinWidth="6">