Indigo
Indigo

Reputation: 2997

How to count only checked items in CheckedListBox dynamically while the user is checking boxes?

I have a CheckedListBox control on my windows form application, which gives a list of items to select from. I want to count and show only checked (not selected) items while the user is still checking them. I mean count as you check them.

I have tried to use ItemCheck event and CheckedListBox.CheckedItems.Count but the problem is that it counts every other click even if the item is unchecked. When I check something it counts and if I unchecked it again, it counts that too.

I think it has to do with the remark given on MSDN "The check state is not updated until after the ItemCheck event occurs." I do not completely understand the problem here.

Thank you.

Upvotes: 4

Views: 26027

Answers (6)

TxCsharper
TxCsharper

Reputation: 656

I know this has been answered long ago, but I found it easier to just handle the MouseUp and KeyUp events. The CheckedItems.Count property is accurate when those events are fired. Since they both do the same thing, I created a method to to the work and called that method from both event handlers.

    private void clbFolders_KeyUp(object sender, KeyEventArgs e) { Update(); }
    private void clbFolders_MouseUp(object sender, MouseEventArgs e) { Update(); }

    private void Update()
    {
        btnDelete.Enabled = clbFolders.CheckedItems.Count > 0;
    }

Upvotes: 0

Sarath Subramanian
Sarath Subramanian

Reputation: 21281

Since we won't get the updated value in the CheckedItems.Count immediately, we use e.NewValue to get the updated value to get whether the state is Checked or not.

Declare a global variable for getting the count

int chkListCount = 0;

In the ItemCheck event give the following code

private void chkList_ItemCheck(object sender, ItemCheckEventArgs e)
{
     if (e.NewValue == CheckState.Checked)
     {
         chkListCount++;
     }
     else if(e.NewValue == CheckState.Unchecked)
     {
         chkListCount--;
     }
}

Its the simple logic to get the count of selected items

Upvotes: 1

Shawn Kovac
Shawn Kovac

Reputation: 1435

Haedrian answered this correctly, but i think raw code goes a long ways too. So here's the C# code:

private void CheckedListBox_ItemCheck(Object sender, ItemCheckEventArgs e)
{
    int sCount = checkedListBox.CheckedItems.Count;
    if (e.NewValue == CheckState.Checked  ) { ++sCount; }
    if (e.NewValue == CheckState.Unchecked) { --sCount; }
    // now sCount is count of selected items in checkedListBox.
}

I had the same issue, and this question and answer gave me the solution. Thanks for the question and already existing answers!

Upvotes: 7

Indigo
Indigo

Reputation: 2997

It is not really a wise and intelligent work as a beginner but at the end solved my problem.

private void CheckedListBox_ItemCheck(Object sender, ItemCheckEventArgs e)
    {
        int count = 0;
        if (e.NewValue.ToString() == "Checked")
        {
            // first get all the checked items
            foreach (object checkeditem in CheckedListBox.CheckedItems)
            {
                string checkItem = CheckedListBox.GetItemCheckState(CheckedListBox.Items.IndexOf(checkeditem)).ToString();
                if (checkItem == "Checked")
                {
                    count = count + 1;
                }
            }
            // Now, below is the most important part considering the remark on MSDN
            // "The check state is not updated until after the ItemCheck event occurs."
            count = count + 1; // Plus 1 as the NewValue was Checked
            labelCount.Text = "You have selected " + count + "Items.";
        }
        else if (e.NewValue.ToString() == "Unchecked")
        {
            // first get all the checked items
            foreach (object checkeditem in CheckedListBox.CheckedItems)
            {
                string checkItem = CheckedListBox.GetItemCheckState(CheckedListBox.Items.IndexOf(checkeditem)).ToString();
                if (checkItem == "Checked")
                {
                    count = count + 1;
                }
            }
            // Now, below is the most important part considering the remark on MSDN
            // "The check state is not updated until after the ItemCheck event occurs."
            count = count - 1; // minus 1 as the NewValue was Unchecked,
            labelCount.Text = "You have Selected " + count + "Items.";
        }
    }  

I would really appreciate comments on this code.

Upvotes: 0

Michal Klouda
Michal Klouda

Reputation: 14521

Add event handler for SelectedIndexChanged and get the count from CheckedItems.Count.

With ItemCheck you don't have the actual value, but value before the last change is processed and you would need to adjust the count according to EventArgs as Haedrian proposed.

Upvotes: 3

Haedrian
Haedrian

Reputation: 4328

The ItemCheckEventArgs parameter has the Property (NewValue) which tells you whether the change is a check, uncheck or neither.

If CheckedItems.Count is not updated until after the event fires (which is what I'm understanding from that remark) - then you can add that count, and see whether the ItemChecckEventArgs is a check (+1) or an uncheck (-1) and you can get the correct total.

(Unless I'm understanding the remark wrongly, its very vague).

Upvotes: 9

Related Questions