Search code examples
c#wpfxamlcheckboxdatatemplate

How to uncheck checkboxes in a DataTemplate?


I have 4 checkboxes in the datagrid. I want to set IsChecked = false on other three checkboxes when a checkbox is activated. Due to the use of DataTemplate, I do not have access to the use of name controls.

Using a sender, I can only access one control at a time. But I want to turn off 3 checkboxes and activate a checkbox.

This is my template:

<DataGridTemplateColumn.CellTemplate>
    <DataTemplate>
        <StackPanel Orientation="Vertical" Margin="5" HorizontalAlignment="Right">
            <Metro:MetroSwitch Checked="chk_Checked" Tag="exc" Margin="0,2"  Name="chkExcelent">خیلی خوب</Metro:MetroSwitch>
            <Metro:MetroSwitch Checked="chk_Checked" Tag="good" Margin="0,2" Name="chkGood">خوب</Metro:MetroSwitch>
            <Metro:MetroSwitch Checked="chk_Checked" Tag="notbad" Margin="0,2" Name="chkNotBad">قابل قبول</Metro:MetroSwitch>
            <Metro:MetroSwitch Checked="chk_Checked" Tag="bad"  Name="chkBad">نیاز به تلاش بیشتر</Metro:MetroSwitch>
        </StackPanel>
    </DataTemplate>
</DataGridTemplateColumn.CellTemplate>

and this is my code-behind:

private void chk_Checked(object sender, RoutedEventArgs e)
{
    switch ((sender as Arthas.Controls.Metro.MetroSwitch).Tag.ToString())
    {
        case "exc": Console.WriteLine("exc"); break;
        case "good": Console.WriteLine("ggg"); break;
        case "notbad": Console.WriteLine("nb"); break;
        case "bad": Console.WriteLine("bad"); break;
    }
}

Solution

  • I don't have your code and markup so I've done this in a simpler view.
    This uses the fact that checking a checkbox is a routed bubbling event.

    <Grid>
        <StackPanel  ToggleButton.Checked="StackPanel_Checked">
            <CheckBox />
            <CheckBox />
            <CheckBox />
            <CheckBox />
        </StackPanel>
    </Grid> 
    

    and

        private void StackPanel_Checked(object sender, RoutedEventArgs e)
        {
            CheckBox cb = e.OriginalSource as CheckBox;
            if(cb.IsChecked == false)
            {
                return;
            }
            foreach (var item in ((StackPanel)sender).Children)
            {
                if(item != cb)
                {
                    ((CheckBox)item).IsChecked = false;
                }
            }
        }
    

    Note that when you change the other checkboxes then their events will fire but the handler will ignore those made false.
    You also have to avoid changing the one the user just checked back.
    I've not stopped the thing firing when you uncheck the one you just checked.
    So you may want to think about this a little more than the 10 minutes I allocated to answering your question.