我在我正在处理的一个小型应用程序中使用 CheckedListBox 控件。这是一个很好的控制,但有一件事困扰着我;我无法设置一个属性,以便它只在我实际选中复选框时检查该项目。克服这个问题的最佳方法是什么?我一直在考虑从复选框的左侧获取鼠标点击的位置。这部分有效,但如果我点击一个空白区域,那么在离左侧足够近的地方仍然会检查当前选定的项目。关于这个有什么想法吗?
6 回答
我知道这个线程有点老了,但我认为提供另一种解决方案不是问题:
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
)。
您可以将那个东西与矩形一起使用,但为什么要让它变得更复杂呢?
好吧,这很丑陋,但是您可以通过挂钩来计算鼠标点击坐标对项目矩形的坐标,CheckedListBox.MouseDown
如下CheckedListBox.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;
}
}
}
另一种解决方案是简单地使用 Treeview。
将 CheckBoxes 设置为 true,将 ShowLines 设置为 false,将 ShowPlusMinus 设置为 false,您的内容与 CheckedListBox 基本相同。只有在单击实际的 CheckBox 时才会检查这些项目。
CheckedListBox 要简单得多,但 TreeView 提供了许多可能更适合您的程序的选项。
我成功地使用了这个属性:
CheckedBoxList.CheckOnClick
CheckedListBox 中复选框的文本默认呈现是在复选框输入之后放置一个 HTML 标签,并将标签的“for”属性设置为复选框的 ID。
当标签表示它是“为”的元素时,单击该标签会告诉浏览器关注该元素,这就是您所看到的。
如果列表是静态的,则两个选项是使用单独的 CheckBox 控件和文本(不是 CheckBox 的 Text 属性,因为它与 CheckBoxList 的作用相同)呈现您自己的列表,或者如果列表是,则使用类似于 Repeater 的东西动态的。
尝试这个。将 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”代码运行时重新关闭。