Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No ItemChecked event in a CheckedListBox?

Tags:

c#

winforms

The ListView control has an ItemCheck event which is fired before the item changes, and an ItemChecked event that is fired after the item changes. See this SO question for more detail.

The CheckedListBox control only has the ItemCheck event.

What is the best way to do something like this with a CheckedListBox?

private void checkedListBox_ItemChecked(object sender ItemCheckedEventArgs e)
{
    okButton.Enabled = (checkedListBox.CheckedItems.Count > 0);
}

Supplemental question: Why is there no CheckedListBox.ItemChecked event?

like image 358
Regan Sarwas Avatar asked Dec 15 '10 19:12

Regan Sarwas


People also ask

Which event will occur when CheckBox or list item is clicked?

Whenever a user clicks a Windows Forms CheckBox control, the Click event occurs.


3 Answers

A nice trick to deal with events that you cannot process when they are raised is to delay the processing. Which you can do with the Control.BeginInvoke() method, it runs as soon as all events are dispatched, side-effects are complete and the UI thread goes idle again. Often helpful for TreeView as well, another cranky control.

    private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e) {         this.BeginInvoke((MethodInvoker)delegate {              okButton.Enabled = checkedListBox1.CheckedItems.Count > 0;         });     } 

Just in case: this has nothing to do with threading and the trick is quite cheap.

Why no ItemChecked event? Not really sure. CheckedListBox just isn't a very good control. Definitely not done by one of the gurus in the original Winforms team.

like image 195
Hans Passant Avatar answered Sep 25 '22 04:09

Hans Passant


    private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e) {         int count = this.checkedListBox1.CheckedItems.Count;         if (e.CurrentValue != CheckState.Checked && e.NewValue == CheckState.Checked) {             count += 1;         } else if (e.CurrentValue == CheckState.Checked && e.NewValue != CheckState.Checked) {             count -= 1;         }         this.okButton.Enabled = count > 0;     } 
like image 28
QYY Avatar answered Sep 23 '22 04:09

QYY


Based on Hans Passant's answer I am adding a generic VB.NET version. I needed one method which would be called for all CheckedListBox controls on the form. You can easily tweak this if you need separate methods for each control (adds some redundancy though).

Public Class Form1
    Delegate Sub ProcessItemCheck(ByRef ListBoxObject As CheckedListBox)

    Private Sub ProcessItemCheckSub(ByRef ListBoxObject As CheckedListBox)
        ' Do your actual ItemCheck stuff here
    End Sub

    Private Sub CheckedListBox1_ItemCheck(ByVal sender As Object, ByVal e As System.Windows.Forms.ItemCheckEventArgs) Handles CheckedListBox1.ItemCheck
        Dim Objects As Object() = {CheckedListBox1}
        BeginInvoke(New ProcessItemCheck(AddressOf ProcessItemCheckSub), Objects)
    End Sub
End Class
like image 23
excitive Avatar answered Sep 24 '22 04:09

excitive