Search code examples
wpfdatagrid

DataGridCheckBoxColumn change default toggle cycle to become checked (true) after was in null state (instead of becoming false)


I'm working on a DataGridCheckBoxColumn whith a custom style like this:

<Style x:Key="StepCheckBox" TargetType="{x:Type CheckBox}" BasedOn="{StaticResource {x:Type CheckBox}}">
    <Setter Property="Background" Value="Transparent" />
    <Setter Property="BorderBrush" Value="#FF262E34"/>
    <Setter Property="Foreground" Value="#FF262E34"/>
    <Setter Property="BorderThickness" Value="0"/>


    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type CheckBox}">

                <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
                    <Border BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" 
                            BorderThickness="{TemplateBinding BorderThickness}" Width="24" Height="24" HorizontalAlignment="Center">
                        <Grid>
                            <Ellipse  Width="24" Height="24" Fill="LightGray" Stroke="DarkGray" Stretch="Uniform" />
                            <Ellipse Name="ellipse" Width="24" Height="24" Fill="LimeGreen" Stretch="Uniform" />
                            <Path Name="mark" Stretch="Uniform" Width="20" Height="14" Fill="White" Data="F1 M 9.97498,1.22334L 4.6983,9.09834L 4.52164,9.09834L 0,5.19331L 1.27664,3.52165L 4.255,6.08833L 8.33331,1.52588e-005L 9.97498,1.22334 Z "/>
                            <Label x:Name="markLetter" Content="X" 
                                   Margin="0,-3,0,0" FontSize="14" FontWeight="ExtraBold" Foreground="White"
                                   HorizontalAlignment="Center" VerticalAlignment="Center" />
                        </Grid>
                    </Border>
                    <TextBlock Margin="0,0,0,0"  VerticalAlignment="Center" Foreground="{TemplateBinding Foreground}" Text="{TemplateBinding Content}"></TextBlock>
                </StackPanel>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsChecked" Value="True">
                        <Setter TargetName="ellipse" Property="Fill" Value="LimeGreen"/>
                        <Setter TargetName="mark" Property="Fill" Value="White"/>
                        <Setter TargetName="markLetter" Property="Foreground" Value="Transparent"/>
                    </Trigger>
                    <Trigger Property="IsChecked" Value="{x:Null}">
                        <Setter TargetName="ellipse" Property="Fill" Value="Transparent"/>
                        <Setter TargetName="mark" Property="Fill" Value="Transparent"/>
                        <Setter TargetName="markLetter" Property="Foreground" Value="Transparent"/>
                    </Trigger>
                    <Trigger Property="IsChecked" Value="False">
                        <Setter TargetName="ellipse" Property="Fill" Value="Red"/>
                        <Setter TargetName="mark" Property="Fill" Value="Transparent"/>
                        <Setter TargetName="markLetter" Property="Foreground" Value="White"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>

</Style>

usage:

<DataGridCheckBoxColumn x:Name="dgSteps" Binding = "{Binding Result}"
                                                        Header="Result"
                                                        ElementStyle="{StaticResource StepCheckBox}"
                                                        >
                                    <DataGridCheckBoxColumn.CellStyle>
                                        <Style>
                                            <EventSetter Event="CheckBox.Checked" Handler="OnChecked"/>
                                            <EventSetter Event="CheckBox.Unchecked" Handler="OnChecked"/>
                                        </Style>
                                    </DataGridCheckBoxColumn.CellStyle>
                                </DataGridCheckBoxColumn>

The values are null by default but what I need is that on the first toggle on the checkbox must become checked (true) instead of unchecked (false). What I tried is to change their state in the OnChecked event, but is wrong because the event get called again. Any ideas?


Solution

  • Try this implementation:

    private void OnChecked(object sender, RoutedEventArgs e)
    {
        CheckBox checkBox = (CheckBox)sender;
        if (checkBox.IsChecked == false && checkBox.Tag == null)
        {
            checkBox.IsChecked = true;
            checkBox.Tag = new object();
        }
    }
    

    XAML:

    <DataGridCheckBoxColumn x:Name="dgSteps"
                            Binding="{Binding Result}"
                            Header="Result">
        <DataGridCheckBoxColumn.ElementStyle>
            <Style TargetType="CheckBox" BasedOn="{StaticResource StepCheckBox}">
                <EventSetter Event="Checked" Handler="OnChecked"/>
                <EventSetter Event="Unchecked" Handler="OnChecked"/>
            </Style>
        </DataGridCheckBoxColumn.ElementStyle>
    </DataGridCheckBoxColumn>