Windows C# CheckedListBox Checked Item Event Handling
Asked Answered
W

5

7

I'm currently developing a Window app that uses CheckedListBoxes for certain aspects of the program. A problem I've encountered is that I have been trying to find which event is triggered when an item is checked so that I can enable a form button when any list item is checked.

Problem is that I tried using the following;

private void clbAvailMods_ItemCheck(object sender, ItemCheckEventArgs e)
    {
        if(e.NewValue == CheckState.Checked)
        {
            btnInstall.Enabled = true;
        }
    }

but when I set a breakpoint on the if statement, it never fires upon checking an item in the listbox.

Am I doing something wrong here?

Whiffletree answered 5/7, 2010 at 20:27 Comment(1)
It appears that the Form Designer had a misregistered ItemCheck event in there. That fixed the core issue, but now a new one has arisen that appears more vague in it's context. Apparently a checked item's state is not updated until after ItemCheck is finished. This is bad since I need the first item checked to trigger the embodied code. Since the state is not updated until afterwards, I lose out on the immediate registration of the item check event firing.Whiffletree
H
22

A standard Windows Forms trick is to delay running code until all event side-effects have been completed. You delay running code with the Control.BeginInvoke() method. This will fix your problem:

    private void checkedListBox1_SelectedIndexChanged(object sender, EventArgs e) {
        this.BeginInvoke(new MethodInvoker(evalList), null);
    }

    private void evalList() {
        bool any = false;
        for (int ix = 0; ix < checkedListBox1.Items.Count; ++ix) {
            if (checkedListBox1.GetItemChecked(ix)) {
                any = true;
                break;
            }
        }
        btnInstall.Enabled = any;
    }
Haemic answered 5/7, 2010 at 21:46 Comment(4)
I'll most definitely be looking into this suggestion more. It seems to be on the right track on paper(screen). :) Thanks, Hans.Whiffletree
I think is is going to be the ticket I was looking for. Thank you for the assistance! :)Whiffletree
This worked for me with a combination dodgy_coder solution: https://mcmap.net/q/180952/-delayed-function-calls. Simply add the foo method to your code, then change this line to this.BeginInvoke(new MethodInvoker(foo), null); and finally inside of foo call evalList instead of bar();Nerveracking
The SelectedIndexChanged event is not fired if the checkbox is toggled with the space key.Indusium
P
2

You can use the NewValue property to manually update CheckedItems.Count. This is the code I use to only enable a button when there's at least one item checked:

private void checkedListBoxProds_ItemCheck(object sender, ItemCheckEventArgs e)
{
    this.buttonGenerar.Enabled = ((this.checkedListBoxProds.CheckedItems.Count + (e.NewValue == CheckState.Checked ? 1 : -1)) > 0);
}
Peyton answered 13/9, 2010 at 12:37 Comment(0)
B
0

A couple of potential gotchas. Presumably you've added the event through the VS.Net GUI to ensure that it gets plumbed into the control. Try clicking on an item twice - once to give the item focus and again to toggle the check state - if you want an item to have its check state toggled on first click then set the "CheckOnClick" property to true.

Bork answered 5/7, 2010 at 20:38 Comment(1)
I already have the "CheckOnClick" value set to true. I noticed that Microsnot seems they have overlooked a rather important design element in this case. They'll let you establish what's GOING to change, but not trigger any events once the change is completed. I must say that those morons at MS could require a debugger for a wet dream.Whiffletree
W
0

I think it is the SelectedIndexChanged event but I will confirm right now.

EDIT: SelectedIndexChanged event does work. But that is firing regardless of whether the checkbox was checked. So I would then check the checked state if you want to do that.

But as an aside when I did use the ItemCheck event it did fire when I actually checked the checkbox and not just the text.

Wil answered 5/7, 2010 at 20:41 Comment(2)
Yes, the ItemCheck does fire when you click a checkbox. The real problem is that the vhecked state of that checkbox will still be the opposite of what it was prior to clicking it until after the ItemCheck is finished processing. Hence, the true dilemma of attempting to see if a checkbox is actually checked or unchecked in realtime. i.e. the need for an "ItemCheckChanged" event.Whiffletree
So then can't you just check the opposite? If the itemcheck event is firing and the checkbox is not checked then that means that it is about to be checked correct?Wil
C
0

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;
}
Complaisant answered 4/2, 2017 at 2:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.