4

I use MS Visual 2013 Express, C#, and WPF.

In my program there are six checkboxes, and when one of them is checked, the other five should get unchecked.

I googled the last two hours, but can't find a solution as a beginner in C#. In java, i would just write checkbox1.setSelected(false);

I added a clickevent, a checked and unchecked evet in the C# code. I added Checked and Unchecked in the .xaml, but I don't know hot to get it to work.

Hope you can help me :)

=======================

My solution:

Thank you for your help. I tried some random stuff with "IsChecked" you suggested and get it to work luckily.

.Xaml looks like:

            <CheckBox x:Name="CheckBox1" ... Checked="CheckBox1_Checked"  />
            <CheckBox x:Name="CheckBox2" ... Checked="CheckBox2_Checked"  />
            <CheckBox x:Name="CheckBox3" ... Checked="CheckBox3_Checked"  />
            <CheckBox x:Name="CheckBox4" ... Checked="CheckBox4_Checked"  />
            <CheckBox x:Name="CheckBox5" ... Checked="CheckBox5_Checked"  />
            <CheckBox x:Name="CheckBox6" ... Checked="CheckBox6_Checked"  />

C# code for CheckBox1:

    private void CheckBox1_Checked(object sender, RoutedEventArgs e)
    {
        CheckBox1.IsChecked = true;
        CheckBox2.IsChecked = false;
        CheckBox3.IsChecked = false;
        CheckBox4.IsChecked = false;
        CheckBox5.IsChecked = false;
        CheckBox6.IsChecked = false;
    }

e.g. for CheckBox2:

    private void CheckBox2_Checked(object sender, RoutedEventArgs e)
    {
        CheckBox2.IsChecked = true;
        CheckBox1.IsChecked = false;
        CheckBox3.IsChecked = false;
        CheckBox4.IsChecked = false;
        CheckBox5.IsChecked = false;
        CheckBox6.IsChecked = false;
    }

So in the end, it is a very easy task to do.

StefanS
  • 211
  • 2
  • 3
  • 12
  • 8
    Sounds like a `RadioButton` to me. Why not use that instead; you get this behavior for free! – BradleyDotNET Oct 31 '14 at 19:08
  • @StefanS: For clarification, is this one of those scenarios where only *some* of the options are mutually exclusive? If they're *all* mutually exclusive, then definitely use a RadioButton, as BradleyDotNET suggested. But if only certain ones are mutually exclusive, then Blam's suggestion is probably what you need. – Troy Gizzi Oct 31 '14 at 19:17
  • CheckBox2.IsChecked = false; Looks a lot like my answer. You do know to check an answer. – paparazzo Nov 01 '14 at 12:53

5 Answers5

5
checkbox1.IsChecked = false;

ToggleButton.IsChecked Property

I am reading it as one special that unchecks the other 5.
If you want to have just one checked at a time then RadioButton would do that.
By default you can't uncheck a RadioButton.
This would allow for all 6 unchecked.

I think binding is better and implement INotifyPropertyChanged

private Bool cbSecial = false;
private Bool cb1 = false;
private Bool cb2 = false;
public Bool CbSpecial 
{
   get { return cbSecial; }
   set 
   {
      if (value == cbSecial) return;
      cbSecial = value;
      if (cbSpecial) 
      {
          Cb1 = false;
          Cb2 = false;
          ... 
      }
      NotifyPropertyChanged("CbSpecial");
   }
}
public Bool Cb1 
{
   get { return cb1; }
   set 
   {
      if (value == cb1) return;
      cb1 = value;
      NotifyPropertyChanged("Cb1 ");
   }
}
paparazzo
  • 44,497
  • 23
  • 105
  • 176
  • The part that hurts here is that you have to do this to all the other check boxes. To get "RadioButton" behavior you could use the same binding procedure used in http://stackoverflow.com/questions/397556/how-to-bind-radiobuttons-to-an-enum and it would be a lot better. – BradleyDotNET Oct 31 '14 at 19:20
  • @BradleyDotNET Yeah, I feel weird and dirty about the solution I wrote, but I can't think of a simpler way to do it outside of XAML. Maybe I'll add something with DataTriggers? – furkle Oct 31 '14 at 19:22
  • @furkle You don't need data triggers; just bind them all to the same value and use a `ValueEqualsConverter` works great for radio buttons, doing it for a `CheckBox` would work the same way. – BradleyDotNET Oct 31 '14 at 19:24
  • @BradleyDotNET No it would not be better if you accept the question as worded. "When one of them is checked, the other five should get unchecked." Not when any or a - when one. If it was any then it would not be possible for the other 5 to me checked. – paparazzo Oct 31 '14 at 19:24
  • @Blam Yes, but how do you know which other one was previously checked? – furkle Oct 31 '14 at 19:25
  • @Blam I don't understand your point. When one is checked, uncheck the rest. You could certainly keep track of the last one and uncheck it; but thats a whole lot of work, and you *still* have to iterate to get the checked value. A bound solution would be far simpler (once you get the base MVVM code done). Or just use a radio button, which should still be bound. – BradleyDotNET Oct 31 '14 at 19:27
  • @furkle What do you care? When box X is checked you uncheck the other 5. If they are not checked then unchecking does nothing. – paparazzo Oct 31 '14 at 19:27
  • Isn't this all a moot point as OP asked about how to make the checkbox unchecked? Yes there are better ways OP could design the code, but this does answer the question of `"how do make a checkbox unchecked?"` – Nyra Oct 31 '14 at 19:29
  • @BradleyDotNET Let me try one more time. I read it as 5 that he want to allow checked. There is a special 6th that when checed uncheck the other 5. That is the only way you could have the other 5 checked. I read it as one is not the same as any. – paparazzo Oct 31 '14 at 19:30
  • @Blam Ah, then yes; we simply interpreted the question differently. This solution (while it would still work with a bound solution, which is a better *overall* approach) will solve that problem adequately. I read it as looking for a RadioButton functionality. Thanks for taking the time to clarify!. – BradleyDotNET Oct 31 '14 at 19:31
  • @BradleyDotNET At risk of clogging up the comments further, can you expound on/give reference for the idea behind the ValueEqualsConverter? – furkle Oct 31 '14 at 19:36
  • @furkle The question I linked to in my first comment on this post; the top answer has the ValueEqualsConverter code I use in my production code. Is that what you are asking? You *would* have to slightly modify it for checkboxes, but its as simple as replacing `Binding.DoNothing` with `false`. – BradleyDotNET Oct 31 '14 at 19:37
  • @BradleyDotNET Ah, I thought you were talking about a built-in converter with that name and all I was seeing was EnumBooleanConverter. Perfect, thanks! – furkle Oct 31 '14 at 19:41
3

BradleyDotNET is correct - having any given CheckBox in a group uncheck the rest of them is essentially the function of a RadioButton, and you don't end up needing to do anything to implement this sort of behavior.

But, if you really wanted to use CheckBoxes instead, one way you could accomplish that is to keep reference to each of the CheckBox IsChecked value in a property within your ViewModel that you've TwoWay bound, and also keep an internal IEnumerable of your six values, like so:

private bool? checkBox1IsChecked = false;
public bool? CheckBox1IsChecked 
{ 
    get { return checkBox1IsChecked;
    set
    {
        UncheckAllCheckBoxes();
        checkBox1IsChecked = true;
    }
}
public bool? CheckBox2IsChecked { get; set; }
...

// include 1 through 6 here
private List<bool?> yourCheckStates = new List<bool> { checkBox1IsChecked, ... };

You could use something like this every time the status changes on one of them:

private void UncheckAllCheckBoxes()
{
    foreach (bool? cbIsChecked in yourCheckStates)
    {
        cb.IsChecked = false;
    }
}

And then set the value of the one that's just been changed to true. Each time a checkbox is checked, the other five will always be unchecked.

Edit: If I've misread this, as Blam is suggesting, and you meant that one CheckBox in particular unchecks all the others, then only include the call to UncheckAllCheckBoxes() within the property for that specific CheckBox's IsChecked value, and add a line to set that one special CheckBox's IsChecked to false in all the other setters.

furkle
  • 5,019
  • 1
  • 15
  • 24
1

You can go one of two ways about this:

  1. RadioButtons in a group
  2. Selector with a customized ItemTemplate

RadioButtons:

<RadioButton GroupName="MyGrouping" Content="Option 1" IsChecked="True"/>
<RadioButton GroupName="MyGrouping" Content="Option 2" />
<RadioButton GroupName="MyGrouping" Content="Option 3" />

Selector:

<ListBox ItemsSource="{Binding Path=MyOptions}">
  <ListBox.ItemTemplate>
    <DataTemplate>
        <RadioButton Content="{Binding}"
            IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}, Path=IsSelected}" />
    </DataTemplate>
  </Listbox.ItemTemplate>
</ListBox>

Note: I selected ListBox as an example, but you can select anything that derives from Selector.

myermian
  • 31,823
  • 24
  • 123
  • 215
0
 {
    if (CheckBox1.Checked)
    {Label1.Text = "Checked Apple"; }
    if (CheckBox1.Checked == false)
    {
        Label1.Text = "Unchecked Apple";
    }

}
protected void CheckBox2_CheckedChanged(object sender, EventArgs e)
{
    if (CheckBox2.Checked)
    { Label1.Text = "Checked Banana"; }
    if (CheckBox2.Checked == false)
    {
        Label1.Text = "Unchecked Banana";
    }
}
0

You might find this useful. I had a "Logging Level" wpf menu that I wanted only 1 selection active at a time (i.e. uncheck all the other menu items when selected). My trick was to use the FindName() method and a "tag" option in the xaml (to generate the names for a nice for loop). This way I avoided having a bunch of "=false" lines, and just a single shared function call for each form item.

<MenuItem Header="Logging">
  <!-- let's use the cool TAG propery to store the debugLevel code. We don't use it, but the idea is cool -->
  <MenuItem Tag="0" Name="mnuLogging0" Header="None" IsCheckable="True" Checked="mnuLogging_Checked"  />
  <MenuItem Tag="1" Name="mnuLogging1" Header="Normal" IsCheckable="True" Checked="mnuLogging_Checked"  />
  <MenuItem Tag="2" Name="mnuLogging2" Header="Debug Level 1" IsCheckable="True" Checked="mnuLogging_Checked"  />
  <MenuItem Tag="3" Name="mnuLogging3" Header="Debug Level 2" IsCheckable="True" Checked="mnuLogging_Checked"   />
</MenuItem>

And the function to uncheck the other options, along with bonus code for saving the settings is:

private void mnuLogging_Checked(object sender, RoutedEventArgs e) {
  int LogLevel = Convert.ToInt32( ((MenuItem)sender).Tag.ToString());
  Properties.Settings.Default["LogLevel"] = LogLevel.ToString();
  Properties.Settings.Default.Save();
  // Uncheck everybody but me (as determine by "Tag")
  for (int i=0; i < 4; i++) {
    MenuItem item = Main.FindName("mnuLogging"+i) as MenuItem;
    if (i != LogLevel) item.IsChecked = false;
  }
}