0

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?

Mike97
  • 596
  • 5
  • 20
  • Not sure about changing state in the events, that sounds like a bad plan. You need isthreestate false. If the row isn't in edit mode when you're doing your clicking then you need to make the checkbox immediately responsive. – Andy Nov 13 '22 at 11:43
  • https://stackoverflow.com/questions/3833536/how-to-perform-single-click-checkbox-selection-in-wpf-datagrid – Andy Nov 13 '22 at 11:44
  • Hi @Andy thanks to take the time for this. BTW as I already told my self changing state in the event is wrong, why I posted a question. I apologize if I was not clear but the checkbox is and must be three state. What I want is to change the cycle: if was null then must become true instead of false. if was false must become true, if was true must become false. For the third state, which depends on the datacontext anyway, can be null or become again null using a context menu. All three states comes and goes from and to a SQL database. – Mike97 Nov 13 '22 at 12:06
  • And is ready to be clickable because of the custom style I guess. So no need to be focused. At least is not the problem here. – Mike97 Nov 13 '22 at 12:13
  • 1
    I'd consider a custom control. Replace the behaviour in togglebutton which checkbox inherits. https://source.dot.net/#PresentationFramework/System/Windows/Controls/Primitives/ToggleButton.cs,490b99387e5fd4e0 – Andy Nov 13 '22 at 12:35
  • @Andy yes, looking at OnToggle() function on the source you linked is what I need. The bad is that I cannot find anything to everride in the DataGridCheckBoxColumn class, but yes your suggestion is right. – Mike97 Nov 13 '22 at 12:45
  • Uses a datagridtemplatecolumn – Andy Nov 13 '22 at 14:02

1 Answers1

1

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>
mm8
  • 163,881
  • 10
  • 57
  • 88
  • Hi @mm8, I'll be glad to try your interesting suggestions in some days as I am on a trip. I'll let you know and tanks to had taken the time. – Mike97 Nov 15 '22 at 20:00