Home > Software engineering >  Detect if any checkbox is unchecked to update a list of checkboxes
Detect if any checkbox is unchecked to update a list of checkboxes

Time:12-08

I have 2 lists of initially checked checkboxes, I need to know if any checkbox (on the left) is unchecked by the user in order to update the corresponding checkbox status on the right side without looping for the change state of the checkboxes each time the user clicks :

enter image description here

This is my solution to create the lists so far :

        List<string> statuts_gauche = new List<string> { "005", "006" , "017" , "030", "031", "033", "035", "036", "026", "009", "022", "328", "329"};
    List<string> statuts_droite = new List<string>();
    

    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Console.WriteLine("hello");
        foreach (Control c in this.Controls)
        {
            if (c is CheckBox)
            {
                CheckBox box= (CheckBox)c;
                Console.WriteLine("hh - "   box.Text   " : "   box.Checked );
            }
        }
    }
    private void Form1_Shown(object sender, EventArgs e)
    {

        Create_Checkboxes_ByTag("statuts_gauche",40);
        statuts_droite = statuts_gauche;
        Create_Checkboxes_ByTag("statuts_droite", 300);

    }

    private void Create_Checkboxes_ByTag(String Tag,int initialOffset,int y_position = 30) {
        CheckBox box;

        for (int i = 0; i < statuts_gauche.Count; i  )
        {
            box = new CheckBox();
            box.Tag = Tag;
            box.Text = statuts_gauche[i].ToString();
            box.AutoSize = true;
            box.Checked = true;
            box.Location = new Point(initialOffset, y_position);
            y_position = y_position   40;
            this.Controls.Add(box);
        }
    }

CodePudding user response:

private void chkLeft_CheckedChanged(object sender, EventArgs e)
{
    if (sender as CheckBox lchk)
    {
        string name = lchk.Name.Replace("Left", "Right");
        CheckBox rchk = pnlRight.Controls(name) as CheckBox;
        rchk.Checked = lchk.Checked;
    }
}

^ This code is assuming implementation details you didn't provide. First, for all the 'left' checkboxes, you would add this generic event handler to each of their CheckedChanged events. IE, something like:

foreach (ctl in pnlLeft.Controls)
{
    if (ctl as CheckBox chk)
    {
        ctl.CheckedChanged  = chkLeft_Changed;
    }
}

This is also assuming that you have the left checkboxes in one parent container control and the right checkboxes are in a different parent container. Of course if they share a container, then you are going to have to filter on name in the above foreach loop.

Next, it's assuming that you named your controls something like 'chkLeft022' and 'chkRight022', so that their names are tightly paired and all you need to get the right from the left (or vice versa) is just a simple string replacement of the word left or right in the name of the control.

You could go a nameless route where it's just index based (like pnlLeft.Controls[0] paired with pnlRight.Controls[0]) but then you need to make sure that order is always correct.

CodePudding user response:

If you're willing to create your boxes at the same time you can tie them together easily:

private void Create_Checkboxes_ByTag(string tag,int initialOffsetLeft, int initialOffsetRight,int y_position = 30) {
   
    for (int i = 0; i < statuts_gauche.Count; i  )
    {
        var box = new CheckBox() {
          Tag = tag,
          Text = statuts_gauche[i].ToString(),
          Checked = true,
          Location = new Point(initialOffsetLeft, y_position)
        };
        this.Controls.Add(box);

        var boxr = new CheckBox() {
          Tag = Tag,
          Text = statuts_gauche[i].ToString(),
          Checked = true,
          Location = new Point(initialOffsetRight, y_position)
        };
        this.Controls.Add(box);

        box.CheckedChanged  = (_,_) => boxr.Checked = box.Checked;

        y_position = y_position   40;
    }
}

A helper method could clean that up some too..

If you want to stick with creating a single column of boxes at once, add the boxes to a list as you create them and return it. Pass the list in the next time you call (create the right hand boxes) and then you can locate the equivalent left hand box by index in order to add an event handler to the left that refs the right, perhaps:

private List<CheckBox> Create_Checkboxes_ByTag(string tag, int initialOffset, List<CheckBox> lefts = null, int y_position = 30) {
   
    var boxes = new List<CheckBox>();
    for (int i = 0; i < statuts_gauche.Count; i  )
    {
        var box = new CheckBox() {
          Tag = tag,
          Text = statuts_gauche[i].ToString(),
          Checked = true,
          Location = new Point(initialOffsetLeft, y_position);
        };
        this.Controls.Add(box);

        boxes.Add(box);

        var leftBox = lefts?[i];
        if(leftBox != null)
          leftBox.CheckedChanged  = (_,_) => box.Checked = leftBox.Checked;

        y_position = y_position   40;
    }
    return boxes;
}

Then you just have to capture the return list the first time you call it and feed it back in the next time you call.

  • Related