Я использую элемент управления CheckedListBox в небольшом приложении, над которым работаю. Это хороший контроль, но меня беспокоит одна вещь; Я не могу установить свойство, чтобы оно проверяло элемент только тогда, когда я действительно устанавливаю флажок. Каков наилучший способ преодолеть это? Я думал о том, чтобы получить положение щелчка мыши относительно левой стороны флажка. Что частично работает, но если я нажму на пустое место, достаточно близко слева, текущий выбранный элемент все равно будет проверен. Любые идеи по этому поводу?
CheckedListBox Control — установка флажка только при щелчке фактического флажка
Ответы (6)
Ну, это довольно уродливо, но вы можете вычислить координаты попадания мыши по прямоугольникам элементов, перехватив 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;
}
}
}
Я знаю, что эта ветка немного устарела, но я не думаю, что проблема предложить другое решение:
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
).
Вы могли бы использовать эту штуку с прямоугольником, но зачем делать ее более сложной, если это необходимо.
Другое решение — просто использовать Treeview.
Установите для CheckBoxes значение true, для ShowLines — false, а для ShowPlusMinus — false, и вы получите практически то же самое, что и CheckedListBox. Элементы проверяются только при нажатии фактического CheckBox.
CheckedListBox намного проще, но TreeView предлагает множество опций, которые потенциально лучше подходят для вашей программы.
Я успешно использовал это свойство:
CheckedBoxList.CheckOnClick
Текст для флажка в CheckedListBox отображается по умолчанию, чтобы поместить метку HTML после ввода флажка и установить для атрибута метки «для» идентификатор флажка.
Когда метка обозначает элемент, для которого она предназначена, щелчок по этой метке указывает браузеру сфокусироваться на этом элементе, что вы и видите.
Два варианта: визуализировать собственный список с отдельными элементами управления CheckBox и текстом (не как свойство Text CheckBox, так как оно делает то же самое, что и CheckBoxList), если список является статическим, или использовать что-то вроде повторителя, если список динамичный.
Попробуй это. Объявите 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 пикселях отмеченного списка (область флажка), работает всегда, за исключением повторной проверки выбранного в данный момент элемента. Сохранение последнего индекса и выход без изменений позволяет собственному коду обрабатывать это правильно, попытка установить для него значение «checked» в этом случае включает его, и он просто отключается при запуске кода «ItemCheck».