Is this possible?

I am trying to modify how the CheckListBox works when a user clicks on an item. By default there are two options. One requires the user to "select" the item first and then they can check it, meaning 2 clicks. The other is they click the item and it checks that item.

I'd like to combine the two, so that if a user clicks the text of the item it highlights it and "selects" it, and if they click it again it will check it. But I also would like it so that if a user clicks the checkbox it will select the item and check it at the same time.

I'm guessing here, but I think I would need to override the OnSelectedIndexChanged method and find out if the user clicked the text part of the item or the checkbox part.

Any ideas or suggestions would be appreciated!

Recommended Answers

All 6 Replies

Set the CheckOnClick property to true;

private void Form1_Load(object sender, EventArgs e)
{
   checkedListBox1.Items.Add("me");
   checkedListBox1.Items.Add("you");
   checkedListBox1.Items.Add("us");

   checkedListBox1.CheckOnClick = true;
}

If I do that, then the user can just click the text to check it. I want to prevent that. I'm trying to get it so if the user clicks the text itself nothing happens except the item becomes highlighted but if the user clicks the checkbox of a non-highlighted item, it will check it and highlight it. If I have CheckOnClick to true, then it's too easy for someone to accidentally check something and having to click each item twice is not all that efficient.

The way I look at it is:

  1. If the user clicks the text, they intend to highlight/select that item, not necessarily check it.
  2. If the user clicks the text, or checkbox of a highlighted/selected item, they intend to check that item.
  3. If the user clicks the checkbox and not the text, regardless of if the item is highlighted/selected, they intend to check that item.

If I set CheckOnClick to true, everything is checked, no matter where they click.

But if there was a way for me to know if the checkbox portion of the item was clicked, I can mark that one as checked myself. Does that make sense?

...then set it to false.

Sounds like you should make your own control.

Basically a combination of a label and a checkbox with no text would work. Clicking on the label (the text portion) would fire the select event handler, while clicking on the checkbox would fire the check handler. Although I could just be an idiot and there's events built in that do just this.

thines01,

If i set it to false, then when the user clicks the checkbox of a non-selected item, it just selects the item and does not check it. The user has to click twice to check the items in the list and if you are checking 5 things in a row that's 10 clicks, and while it's not much, I can see it being an annoyance.

skatamatic,

I think you might be right, but I'm not sure yet, I'm determined to figure this one out. If I do I'll post it up as a code snippet, it boggles my mind that this isn't a standard option, but meh, it's okay, I like the challenges :)

Got it!

I added this code to my control's MouseClick event. It probably needs some cleaning up, but it works perfectly:

    private void MyCustomCheckedListBox_MouseClick(object sender, MouseEventArgs e)
    {
        // Uncomment the lines below to draw a blue box around the checkbox margain. This is useful if you want to change the click area, by providing a 
        // graphical representation of the area.
        //Pen MyPen = new Pen(Color.Blue);
        //MyPen.Width = 1;

        //CreateGraphics().DrawRectangle(MyPen, 0, 0, 15, Height);

        //MyPen.Dispose();

        // If CheckOnClick is true, just return otherwise once an item's checkbox is clicked, the check is immediately reversed.
        if (CheckOnClick)
        {
            return;
        }

        // If the selected item hasn't changed, just return otherwise once an item's checkbox is clicked, the check is immediately reversed.
        if (SelectedIndex == LastSelection)
        {
            return;
        }

        // The last item selected.
        LastSelection = SelectedIndex;

        // Only toggle item checks if the left button is clicked.
        if (e.Button == System.Windows.Forms.MouseButtons.Left)
        {
            // Only toggle item checks if the left-click was within the margin of the checkbox (15px)
            if (e.X <= 15)
            {
                // Reverse whatever check state is currently set.
                switch (GetItemCheckState(SelectedIndex))
                {
                    case CheckState.Checked:
                        SetItemCheckState(SelectedIndex, CheckState.Unchecked);
                        break;
                    case CheckState.Indeterminate:
                        SetItemCheckState(SelectedIndex, CheckState.Checked);
                        break;
                    case CheckState.Unchecked:
                        SetItemCheckState(SelectedIndex, CheckState.Checked);
                        break;
                }                   
            }
        }
    }
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.