views:

806

answers:

3

I'm using a CheckedListBox control in a small application I'm working on. It's a nice control, but one thing bothers me; I can't set a property so that it only checks the item when I actually check the checkbox. What's the best way to overcome this? I've been thinking about getting the position of the mouseclick, relative from the left side of the checkbox. Which works partly, but if I would click on an empty space, close enough to the left the current selected item would still be checked. Any ideas regarding this?

A: 

you could use an extra label, just the checkbox list, and then create labels,.. it's not that nice solved but it works :>

Tyzak
A: 

The text for a checkbox in a CheckedListBox is rendered by default is to place an HTML label after the checkbox input and set the label's "for" attribute to the ID of the checkbox.

When a label is denoting an element that it is "for," clicking on that label tells the browser to focus on that element, which is what you're seeing.

Two options are to render your own list with separate CheckBox controls and text (not as the Text property of the CheckBox, as that does the same thing as the CheckBoxList) if the list is static or to use something like a Repeater if the list is dynamic.

Kevin Gorski
It's not a webform, but a winform :)But I get your drift. The focussing is fine and actually what I want, I just don't want the checkbox checked when clicking on the item itself. Seems I'm gonna fiddle around with a custom control :)
Oxymoron
Ok, it's hard to tell when there was only c# and CheckedListBox as the tags. I went ahead and added winforms.
Kevin Gorski
+1  A: 

Well, it is quite ugly, but you could calculate mouse hit coordinates against rectangles of items by hooking on CheckedListBox.MouseDown and CheckedListBox.ItemCheck like the following

/// <summary>
/// In order to control itemcheck changes (blinds double clicking, among other things)
/// </summary>
bool AuthorizeCheck { get; set; }

private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
{
    if(!AuthorizeCheck)
        e.NewValue = e.CurrentValue; //check state change was not through authorized actions
}

private void checkedListBox1_MouseDown(object sender, MouseEventArgs e)
{
    Point loc = this.checkedListBox1.PointToClient(Cursor.Position);
    for (int i = 0; i < this.checkedListBox1.Items.Count; i++)
    {
        Rectangle rec = this.checkedListBox1.GetItemRectangle(i);
        rec.Width = 16; //checkbox itself has a default width of about 16 pixels

        if (rec.Contains(loc))
        {
            AuthorizeCheck = true;
            bool newValue = !this.checkedListBox1.GetItemChecked(i);
            this.checkedListBox1.SetItemChecked(i, newValue);//check 
            AuthorizeCheck = false;

            return;
        }
    }
}
Dynami Le Savard
Yeah, like I said in the OP, I was thinking about something like this as well, but since it doesn't feel really good I started looking for alternatives :)
Oxymoron
Thanks, it just works! Some optimizations are possible, but the idea works!
nightcoder