CheckedListBox Control - Only checking the checkbox when the actual checkbox is clicked

前端 未结 6 712
故里飘歌
故里飘歌 2021-01-02 01:14

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 th

相关标签:
6条回答
  • 2021-01-02 01:23

    Try this. Declare iLastIndexClicked as a form-level int variable.

    private void chklst_MouseClick(object sender, MouseEventArgs e)
    {
      Point p = chklst.PointToClient(MousePosition);
      int i = chklst.IndexFromPoint(p);
      if (p.X > 15) { return; } // Body click. 
      if (chklst.CheckedIndices.Contains(i)){ return; } // If already has focus click anywhere works right.
     if (iLastIndexClicked == i) { return; } // native code will check/uncheck
      chklst.SetItemChecked(i, true);  
      iLastIndexClicked = i;
    }
    

    Just checking to see if the user clicked in the leftmost 15 pixels of the checked list (the check box area) works at all times except re-checking a currently selected item. Storing the last index and exiting without changing lets the native code handle that properly, trying to set it to checked in that case turns it on and it just turns back off when the "ItemCheck" code runs.

    0 讨论(0)
  • 2021-01-02 01:28

    I succesfully used this property:

    CheckedBoxList.CheckOnClick

    https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.checkedlistbox.checkonclick?view=netframework-4.7.2

    0 讨论(0)
  • 2021-01-02 01:29

    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;
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-02 01:35

    I know this thread's a bit old, but I don't think it's a problem to offer another solution:

    private void checkedListBox1_MouseClick(object sender, MouseEventArgs e)
    {
        if ((e.Button == MouseButtons.Left) & (e.X > 13))
        {
            this.checkedListBox1.SetItemChecked(this.checkedListBox1.SelectedIndex, !this.checkedListBox1.GetItemChecked(this.checkedListBox1.SelectedIndex));
        }
    }
    

    (With the value of CheckOnClick = True).

    You could use that thingy with the rectangle, but why make it more complex the it needs to.

    0 讨论(0)
  • 2021-01-02 01:38

    Another solution is to simply use a Treeview.
    Set CheckBoxes to true, ShowLines to false, and ShowPlusMinus to false and you have basically the same thing as a CheckedListBox. The items are only checked when the actual CheckBox is clicked.

    The CheckedListBox is much more simplistic, but the TreeView offers a lot of options that can potentially be better suited for your program.

    0 讨论(0)
  • 2021-01-02 01:47

    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.

    0 讨论(0)
提交回复
热议问题