【问题标题】:CheckedListBox Control - Only checking the checkbox when the actual checkbox is clickedCheckedListBox 控件 - 仅在单击实际复选框时才检查复选框
【发布时间】:2010-01-19 14:02:58
【问题描述】:

我在我正在开发的一个小型应用程序中使用 CheckedListBox 控件。这是一个很好的控制,但有一件事困扰着我;我无法设置一个属性,以便它仅在我实际选中复选框时检查该项目。 克服这个问题的最佳方法是什么? 我一直在考虑从复选框的左侧获取鼠标点击的位置。这部分有效,但如果我点击一个空白区域,那么在离左侧足够近的地方仍然会检查当前选定的项目。对此有何想法?

【问题讨论】:

  • 你可以使用一个额外的标签,只是复选框列表,然后创建标签,.. 解决的不是很好,但它有效:>
  • 也许我错过了什么。当您选中该框时,现在发生了什么?没有?它是否默认检查某些内容?您想阻止正在发生的事情?
  • 我只希望在单击框本身时选中该框,而不是该行。想象它看起来像: [ ] Item1 目前,当单击整个项目时,该框会被选中,但我不希望这样。我只希望在单击框本身时单击它,而不是单击它旁边的描述性文本。

标签: c# winforms checkedlistbox


【解决方案1】:

我知道这个帖子有点老了,但我不认为提供另一个解决方案是个问题:

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

(值为CheckOnClick = True)。

你可以将那个东西与矩形一起使用,但为什么要让它变得更复杂呢?

【讨论】:

    【解决方案2】:

    好吧,这很丑陋,但是您可以通过挂钩 CheckedListBox.MouseDownCheckedListBox.ItemCheck 来计算鼠标点击坐标与项目的矩形,如下所示

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

    【讨论】:

    • 是的,就像我在 OP 中所说的那样,我也在考虑这样的事情,但由于感觉不太好,我开始寻找替代方案 :)
    • 谢谢,它确实有效!一些优化是可能的,但这个想法很有效!
    【解决方案3】:

    另一种解决方案是简单地使用 Treeview。
    将 CheckBoxes 设置为 true,将 ShowLines 设置为 false,将 ShowPlusMinus 设置为 false,您的内容与 CheckedListBox 基本相同。只有当实际的 CheckBox 被点击时才会检查项目。

    CheckedListBox 更加简单,但 TreeView 提供了许多可能更适合您的程序的选项。

    【讨论】:

      【解决方案4】:

      【讨论】:

        【解决方案5】:

        CheckedListBox 中复选框的文本默认呈现是在复选框输入后放置一个 HTML 标签,并将标签的“for”属性设置为复选框的 ID。

        当标签表示它是“为”的元素时,单击该标签会告诉浏览器关注该元素,这就是您所看到的。

        如果列表是静态的,两个选项是使用单独的 CheckBox 控件和文本呈现您自己的列表(不是作为 CheckBox 的 Text 属性,因为它与 CheckBoxList 做同样的事情)或使用类似中继器的东西,如果列表是动态的。

        【讨论】:

        • 这不是一个网络表单,而是一个 winform :) 但我明白你的意思。聚焦很好,实际上是我想要的,我只是不想在单击项目本身时选中复选框。看来我要摆弄一个自定义控件:)
        • 好吧,很难说什么时候只有 c# 和 CheckedListBox 作为标签。我继续添加了 winforms。
        【解决方案6】:

        试试这个。将 iLastIndexClicked 声明为表单级 int 变量。

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

        除了重新检查当前选中的项目外,只要检查用户在选中列表(复选框区域)的最左边 15 个像素中单击是否始终有效。存储最后一个索引并在不更改的情况下退出可以让本机代码正确处理它,在这种情况下尝试将其设置为已检查将其打开,并在“ItemCheck”代码运行时关闭。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-07-02
          • 2018-10-09
          • 1970-01-01
          • 2012-04-04
          • 2015-12-20
          • 2012-04-18
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多