简体   繁体   中英

One checkBox to check/uncheck ALL other checkBoxes in CheckedListBox (C# winForms)

I have a checkedListBox with 5 CheckBoxes, and I want the first one to be "All". I wrote down this code but i'm getting an endless loop:

private void chkLstBx_ItemCheck(object sender, ItemCheckEventArgs e)
{
    // ----- Get the name of the CheckBox that's changed: -----
    string selected = chkLstBx.SelectedItem + "";
    // ----- If "All" changed: -----
    if (selected.Equals("All"))
        // ----- to TRUE(from unchecked): -----
        if (("" + (chkLstBx.GetItemCheckState(0))).Equals("Unchecked"))
            for (int i = 1; i < chkLstBx.Items.Count; i++)
                **chkLstBx.SetItemChecked(i, true);**
        else // ----- to FALSE(from checked): -----
            for (int i = 1; i < chkLstBx.Items.Count; i++)
                chkLstBx.SetItemChecked(i, false);
// -----------------------------------------------
// -------------- REST OF CODE HERE --------------
// -----------------------------------------------
}

The Bold line (**) unfortunately Calls "chkLstBx_ItemCheck" again... recursively... resulting in an endless loop where the selected is always "All", still "Unchecked", and i begins at 1 once more. How can I solve this?

In this code, notice that this uses the first item in the list as the All item. This is a good practice but a better one is to keep the reference for the all item and use it to check which item is checked in the event handler.

private void chkLstBx_ItemCheck(object sender, ItemCheckEventArgs e)
{
    if (e.Index == 0)
    {
        if (e.NewValue == CheckState.Checked)
            ChangeAllCheckBoxValues(true);
        else
            ChangeAllCheckBoxValues(false);
    }
}

private void ChangeAllCheckBoxValues(bool value)
{
    for (int i = 1; i < chkLstBx.Items.Count; i++)
    {
        chkLstBx.SetItemChecked(i, value);
    }
}

I've tried to look at your code and 2 things that comes to my mind:

1) The reason being is that the binding for ItemCheck was against the chkListBx and not the specific row, as such when you are changing the item check of a specific row, it would call this method again -- finding what was the selected value and call the method again. I was able to make it work by changing the binding to 'SelectedIndexChanged' -- although you may need to check if it works with the rest of your code.

2) When changing the binding into 'SelectedIndexChanged', the behaviour that I got was a little bit of the opposite (ie: the All was still unchecked and all the other checkbox was checked). The reason being was that when it was previously unchecked -- when I clicked it, it set the value to 'Checked' -- and thus when it was being evaluated - the value was considered check -- and it goes to 'unselect' all.

NB: On a side note, its better to always have the braces even for a single line

for (int i = 1; i < chkLstBx.Items.Count; i++)
            chkLstBx.SetItemChecked(i, false);

into

for (int i = 1; i < chkLstBx.Items.Count; i++)
{
    chkLstBx.SetItemChecked(i, false);
}

because if you add a second line intending to be within the loop, you may forgot adding the braces - where the program may still be compile and make it hard to find issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM