Which Checkedlistbox Event Triggers After a Item Is Checked

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
...
}

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;
}

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.

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;

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();
}

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.

User checked item in CheckedListBox

Using the ItemCheck event handler is the correct method for detecting when the user ticks or un-ticks an item in the CheckedListBox. And yes, it will also fire when the item is checked/unchecked programmitically.

If you don't want the event fired when you set/unset items programmatically, you should remove the event handler before hand.

Assuming your event handler looks like this:

private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
{
if (e.NewValue == CheckState.Checked)
{
Debug.Print("Checked");
}
else if (e.NewValue == CheckState.Unchecked)
{
Debug.Print("Un-Checked");
}
}

Before you set/unset items programmatically, you should add the line:

this.checkedListBox1.ItemCheck -= this.checkedListBox1_ItemCheck;

and after the items have been set/unset you in code, re-add the event handler with:

this.checkedListBox1.ItemCheck += this.checkedListBox1_ItemCheck;

Windows C# CheckedListBox Checked Item Event Handling

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;
}


Related Topics



Leave a reply



Submit