0

I have following code which handles the CheckedChanged-event on 12 checkboxes.

private void cbJournal_CheckedChanged(object sender, RoutedEventArgs e)
{
    CheckBox chk = (CheckBox)sender;

    if (chk.IsChecked == true)
    {

        switch (chk.Name)
        {
            case "cbErbbstg":
            {
                month = Months[idxMonth];
                LinkToRSS.Add(link + month);
                RSSname.Add(name);
                Picture.Add(picture);
                ID.Add(100);

            }
            break;

            case "cbGstb":
            {
                month = Months[idxMonth];
                LinkToRSS.Add(link + month);
                RSSname.Add(name);
                Picture.Add(picture);
                ID.Add(200);
            }
            break;
      }
}

Now I want to implement a checkbox which, if checked, checks every other checkbox too, and adds all elements to the lists.

That is, I want to iterate through all cases somehow, so every list can be populated with values.

EDIT: Just fyi: the values added (name, link, etc) are different ones for every checkbox.

Any suggestions?

Mong Zhu
  • 23,309
  • 10
  • 44
  • 76
Allix
  • 170
  • 2
  • 17
  • Create a dictionary where each key element is the name of the checkbox while the value is the Action you want to perform for that checkbox. Now you don't need anymore che switch and you can simply call the method expected for that checkbox. – Steve Oct 04 '17 at 11:05
  • It sounds like that checkbox would have its own handler method which simply adds all of the values to the lists. And sets the other checkboxes to checked. Have you tried writing another handler at all? – David Oct 04 '17 at 11:06
  • Hi, I'm not totally sure to understand what you want to do, but if I got you right, you can define a list of check boxes List checkBoxes; and use it to iterate trough all the boxes, marked as check and of course call the handler using the item in the list as a sender. You will need to initialize your list with all the references to the boxes and do something like. foreach (var checkBox in checkBoxes) { checkbox.Checked = true; cbJournal_CheckedChanged(checkBox, null); } – Guillermo Gutiérrez Oct 04 '17 at 11:10

2 Answers2

3

you can get the list of all checkboxes from the Form.Controls collection:

List<CheckBox> chbList = this.Controls.OfType<CheckBox>().ToList();

now iterate through the list and set the Checked property to true. This way all CheckedChanged events will be fired.

foreach (var chb in chbList)
{
    chb.Checked = true;
}

if you have hooked them to the same event handler you can call the method also directly:

foreach (var chb in chbList)
{
    cbJournal_CheckedChanged(chb, new RoutedEventArgs());
}

EDIT:

If you aer using WPF you need the parent control of the Checkboxes. It my example the Window has a Grid which is the parent of the checkboxes:

Grid myGrid = this.Content as Grid;

List<CheckBox> chbList = myGrid.Children.OfType<CheckBox>().ToList();

Beware in WPF the property is called IsChecked:

foreach (var chb in chbList)
{
    chb.IsChecked = true;
}
Mong Zhu
  • 23,309
  • 10
  • 44
  • 76
  • This approach seems to be exactly what I need/want, thank you! Although, I get a compiler error on `this.Controls`. I added the using directive and also a reference, but it still doesn't recognize it (I'm working with WPF, not Forms, btw.). How do I solve this? – Allix Oct 04 '17 at 11:39
  • @Allix if you use WPF you should may be check out [this answer](https://stackoverflow.com/a/978352/5174469) – Mong Zhu Oct 04 '17 at 11:56
  • Is there no easier way to just add the existing CheckBoxes to a List() and then just iterate through? – Allix Oct 04 '17 at 12:04
  • where are your checkbox controls? in a Grid? – Mong Zhu Oct 04 '17 at 12:12
  • Yes, in a Grid. – Allix Oct 04 '17 at 12:24
  • Yes, but it seems, that the `chbList` is 0 and doesn't get populated with the checkboxes. In my code I know check, if `cbAll` is checked and if so, it should iterate through the List of checkboxes: `CheckBox chk = (CheckBox)sender; Grid gdJournal = this.Content as Grid; List chbList = gdJournal.Children.OfType().ToList(); if (cbAll.IsChecked == true) { foreach (var chb in chbList) { chb.Checked = true; } }` – Allix Oct 04 '17 at 12:33
  • @Allix the property is called `IsChecked` in WPF. my mistake. I edited my post – Mong Zhu Oct 04 '17 at 12:41
  • Yes, I tried this at first but it didn't work either (since the List ist empty) :) Any ideas? – Allix Oct 04 '17 at 12:43
  • you have the wrong container/parent. does your grid have a name? can you access it like a variable? You basically need to get the correct parent. From there on it is easy – Mong Zhu Oct 04 '17 at 13:10
  • 1
    Yup, `var myGrid = (Grid)this.FindName("gdJournal");` did the trick. Again, thank you very much! This approach/solution was exactly what I needed! – Allix Oct 04 '17 at 14:51
1

A possible solution is to create a dictionary where each key element is the name of the checkbox while the value is the Action you want to perform for that checkbox.

Now you don't need anymore che switch and you can simply call the method expected for that checkbox

// Declare this at the class global level
Dictionary<string, Action> checkExecuter = new Dictionary<string, Action>();

// Initialize it somewhere at the start of your class lifetime
checkExecuter.Add("cbErbbstg", OnCbErbbstgChecked);
// add other methods here
checkExecuter.Add("cbAllBox", OnAllBox);

// Action to execute when the cbErbbstg is checked
void OnCbErbbstgChecked()
{
    month = Months[idxMonth];
    LinkToRSS.Add(link + month);
    RSSname.Add(name);
    Picture.Add(picture);
    ID.Add(100);
}

// Action to execute when the cbAllBox is checked
void onAllBox()
{
   foreach(KeyValuePair<string, Action> kvp in checkExecuter)
   {
        if(kvp.Key != "cbAllBox")
           kvp.Value.Invoke();
   }
}

private void cbJournal_CheckedChanged(object sender, RoutedEventArgs e)
{
   CheckBox chk = (CheckBox)sender;
   if (chk.IsChecked && checkExecuter.ContainsKey(chk.Name))
   { 
       checkExecuter[chk.Name].Invoke();
   }
}
Steve
  • 213,761
  • 22
  • 232
  • 286