No Source Available

Which CheckedListBox event triggers after a item is checked?

You can use the ItemCheck event, if you also check the new state of the item which is being clicked. This is available in the event args, as e.NewValue. If NewValue is checked, include the current item along with the collection proper in your logic:

    private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
{
List<string> checkedItems = new List<string>();
foreach (var item in checkedListBox1.CheckedItems)
checkedItems.Add(item.ToString());

if (e.NewValue == CheckState.Checked)
checkedItems.Add(checkedListBox1.Items[e.Index].ToString());
else
checkedItems.Remove(checkedListBox1.Items[e.Index].ToString());

foreach (string item in checkedItems)
{
...
}
}

As another example, to determine if the collection will be empty after this item is (un-)checked:

private void ListProjects_ItemCheck(object sender, ItemCheckEventArgs args)
{
if (ListProjects.CheckedItems.Count == 1 && args.NewValue == CheckState.Unchecked)
// The collection is about to be emptied: there's just one item checked, and it's being unchecked at this moment
...
else
// The collection will not be empty once this click is handled
...
}

No ItemChecked event in a CheckedListBox?

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.

Manage CheckedListBox ItemCheck event to run after an item checked not before

CheckedListBox.ItemCheck Event

The check state is not updated until after the ItemCheck event occurs.

To run some codes after the item checked, you should use a workaround.

Best Option

You can use this option (Thanks to Hans Passant for this post):

private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
{
this.BeginInvoke(new Action(() =>
{
//Do the after check tasks here
}));
}

Another option

  • If in middle of ItemCheck Event, you need to know state of item, you should use e.NewValue instead of using checkedListBox1.GetItemChecked(i)

  • If you need to pass a list of checked indices to a method do this:

Using the code:

var checkedIndices = this.checkedListBox1.CheckedIndices.Cast<int>().ToList();
if (e.NewValue == CheckState.Checked)
checkedIndices.Add(e.Index);
else
if(checkedIndices.Contains(e.Index))
checkedIndices.Remove(e.Index);

//now you can do what you need to checkedIndices
//Here if after check but you should use the local variable checkedIndices
//to find checked indices

Another Option

In middle of ItemCheck event, remove handler of ItemCheck, SetItemCheckState and then add handler egain.

private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
{
var control = (CheckedListBox)sender;
// Remove handler
control.ItemCheck -= checkedListBox_ItemCheck;

control.SetItemCheckState(e.Index, e.NewValue);

// Add handler again
control.ItemCheck += checkedListBox_ItemCheck;

//Here is After Check, do additional stuff here
}

CheckedListBox event *after* CheckState changed

You don't need another event, just handle the ItemChecked and use the e.NewValue to get the count of the checked items after the CheckState is changed and not when the ItemChecked event is raised.

private void NumbersListItemChecked(object sender, ItemCheckEventArgs e)
{
var s = sender as CheckedListBox;
var count = s.CheckedIndices.Count + (e.NewValue == CheckState.Checked ? 1 : -1);

if (count > 5)
e.NewValue = CheckState.Unchecked;

ModifyButton.Enabled = count >= 5;
}

CheckedListBox ItemCheck event only fires on fast double click?

The problem is that the SelectedIndexChanged event gets fired directly after the ItemCheck event. That means it gets fired before every ItemCheck and then immediately after. The label will not show the change as it happens too fast, but switching to MessageBox.Show() verifies that it is getting fired directly after.

C# CheckedListBox.ItemCheck Event

You need to add this handler to your CheckBoxList.ItemCheck event(in form constructor after InitializeComponents() or in Load handler):

checkedListBox1.ItemCheck += checkedListBox1_ItemCheck;

Clear CheckedListBox after ItemCheck Event

Change your code to run the logic after the check state of the item updated:

private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
{
checkedListBox1.BeginInvoke(new Action(() =>
{
if (checkedListBox1.CheckedItems.Count == checkedListBox1.Items.Count)
{
checkedListBox1.Items.Clear();
}
}));
}

According to the documentations, by default, when the ItemCheck event raises, the check state of the item is not updated until after the ItemCheck event occurs. It means it tries to update the check state of the item after running the code that you have in the event handler. As a result in your code, it tries to update item check state after the item removed from items collection and that's why an exception happens. You can see what happens in stack trace, also in source code of the control.

In above code, using BeginInvoke we delay running the code after the check state is updated. You can read more about it in this post.

Get index and name of checked item in checkedListbox

If you check out the Remarks on CheckedListBox.ItemChecked it states

The check state is not updated until after the ItemCheck event occurs.

When you check the first item in your CheckedListBox, your event triggers but the check state of the item has not updated yet. So, there are no items in checkedListBox1.CheckedItems and so there isn't a message box displayed.

When you check a second item, the only item in checkedListBox1.CheckedItems is the one you previously checked. So, that is the one that displays.

I'm assuming from the question that you just want to show the item whose check state is being modified. If so, you can use the ItemCheckEventArgs to get the information you need.

void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
{
MessageBox.Show("Item with title \"" + checkedListBox1.Items[e.Index].ToString() +
"\" was checked. The new check state is " + e.NewValue.ToString();
}

Reliable Way To Cancel ItemCheck Event On CheckedListBox

It is easy to do with the ItemCheck event. Just set the value back. Like this:

    private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e) {
if (someCondition) e.NewValue = e.CurrentValue;
else {
// Regular stuff
//...
}
}


Related Topics



Leave a reply



Submit