The WinForms CheckedListBox
control has 2 default behaviors when clicking with a mouse:
As a convenience feature I needed to allow users to toggle the selection in one click. I have achieved this, so now default behavior #1 above is achieved in one click. The problem is behavior #2 no longer works correctly when clicking the same (i.e., currently selected) item. It works fine when jumping between items, which is desired, but it requires up to 4 clicks on the same item.
My workaround for this is to call the toggling logic twice if the user selects the same item repeatedly. So on to my questions:
Oddly enough debugging the code reveals that the checked state has changed but it doesn't appear on the UI side till it's called twice. I thought it might be threading related but it's not a re-entrant event being triggered that might need BeginInvoke
usage.
Here's my code:
using System.Linq;
using System.Windows.Forms;
namespace ToggleCheckedListBoxSelection
{
public partial class Form1 : Form
{
// default value of -1 since first item index is always 0
private int lastIndex = -1;
public Form1()
{
InitializeComponent();
CheckedListBox clb = new CheckedListBox();
clb.Items.AddRange(Enumerable.Range(1, 10).Cast<object>().ToArray());
clb.MouseClick += clb_MouseClick;
this.Controls.Add(clb);
}
private void clb_MouseClick(object sender, MouseEventArgs e)
{
var clb = (CheckedListBox)sender;
Toggle(clb);
// call toggle method again if user is trying to toggle the same item they were last on
// this solves the issue where calling it once leaves it unchecked
// comment these 2 lines out to reproduce issue (use a single click, not a double click)
if (lastIndex == clb.SelectedIndex)
Toggle(clb);
lastIndex = clb.SelectedIndex;
}
private void Toggle(CheckedListBox clb)
{
clb.SetItemChecked(clb.SelectedIndex, !clb.GetItemChecked(clb.SelectedIndex));
}
}
}
To reproduce my problem comment out the lines mentioned in the code comments and follow these steps:
Thanks for reading!
As a convenience feature I needed to allow users to toggle the selection in one click.
I'm not sure what's happening with the code, but setting CheckOnClick to true
will do this:
CheckOnClick indicates whether the check box should be toggled whenever an item is selected. The default behavior is to change the selection on the first click, and then have the user click again to apply the check mark. In some instances, however, you might prefer have the item checked as soon as it is clicked.