2010-01-19 158 views
9

我在使用我正在处理的小应用程序中的CheckedListBox控件。这是一个很好的控制,但有一件事困扰我;我无法设置属性,以便在我实际选中复选框时仅检查项目。 解决这个问题的最好方法是什么? 我一直在考虑获取鼠标点击的位置,相对于复选框的左侧。哪部分工作,但如果我点击一个空的空间,足够靠近左边,当前选定的项目仍然会被检查。有关这个的任何想法?CheckedListBox控件 - 仅当点击实际复选框时才选中复选框

+0

也许我错过了一些东西。当你检查盒子时现在发生了什么?没有?它是否默认检查某些东西?你想停止发生什么事情? – hunter 2010-01-19 14:40:11

+0

我只想点击盒子本身而不是线条来检查盒子。想象一下,它看起来像: []项目1 目前,对整个项目,当点击该框被选中,但我不希望出现这种情况。我只希望当我点击箱子本身,而不是描述性文本旁边它被点击。 – Oxymoron 2010-01-19 14:46:17

+0

你可以使用额外的标签,只是复选框列表,然后创建标签,.. 这不是很好的解决,但它的工作原理:> – Tyzak 2010-01-19 14:14:10

回答

7

嗯,这是很丑陋,但你可以通过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; 
     } 
    } 
} 
+0

是的,就像我在OP中所说的那样,我也在想这样的事情,但是因为它感觉不太好,所以我开始寻找替代品:) – Oxymoron 2010-01-20 06:34:53

+2

谢谢,它只是起作用!一些优化是可能的,但这个想法很有效! – nightcoder 2010-04-29 14:13:50

0

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

当一个标签表示一个“for”的元素时,点击该标签会告诉浏览器关注该元素,这就是你所看到的。

两个选项来渲染自己的列表与独立的CheckBox控件和文本(不是CheckBox的Text属性,如,做了同样的事情的CheckBoxList)如果该列表是静态的或使用的东西就像一个中继器如果列表是动态的。

+0

这不是一个网络表格,但一个winform :) 但我得到你的漂移。聚焦是好的,实际上我想要的,我只是不希望点击项目本身时选中复选框。似乎我会摆弄自定义控件:) – Oxymoron 2010-01-19 15:09:06

+0

好吧,很难说只有c#和CheckedListBox作为标签。我继续并添加了winforms。 – 2010-01-20 00:45:21

9

我知道这个线程是有点老了计算鼠标击中坐标下的项目的矩形,但我不” t认为这是一个问题提供另一种解决方案:

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)。

你可以在矩形中使用那些东西,但为什么使它更复杂,它需要。

5

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

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

0

试试这个。将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”代码运行时将其打开并关闭。