Элемент управления CheckedListBox - проверять флажок только при нажатии фактического флажка - PullRequest
10 голосов
/ 19 января 2010

Я использую элемент управления CheckedListBox в небольшом приложении, над которым я работаю. Это хороший контроль, но меня беспокоит одна вещь; Я не могу установить свойство, чтобы оно проверяло элемент, только когда я на самом деле отмечал этот флажок. Какой лучший способ преодолеть это? Я думал о том, чтобы получить положение щелчка мышью относительно левой части флажка. Это работает частично, но если бы я щелкнул по пустому пространству, достаточно близко слева, текущий выбранный элемент все равно будет проверен. Есть идеи по этому поводу?

Ответы [ 6 ]

11 голосов
/ 02 января 2011

Я знаю, что этот поток немного староват, но я не думаю, что есть проблема предложить другое решение:

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

Вы можете использовать эту штуку с прямоугольником, но зачем делать его более сложным, чем нужно.

7 голосов
/ 20 января 2010

Ну, это довольно уродливо, но вы можете вычислить координаты попадания мыши по прямоугольникам предметов, подключив 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;
        }
    }
}
6 голосов
/ 11 февраля 2012

Другое решение заключается в простом использовании Treeview.
Установите для CheckBoxes значение true, для ShowLines - значение false, а для ShowPlusMinus - значение false, и вы получите в основном то же самое, что CheckedListBox. Элементы проверяются только при нажатии фактического флажка.

CheckedListBox гораздо проще, но TreeView предлагает множество опций, которые потенциально могут лучше подходить для вашей программы.

1 голос
/ 19 января 2019

Я успешно использовал это свойство:

CheckedBoxList.CheckOnClick

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

0 голосов
/ 09 января 2018

Попробуй это. Объявите 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.

0 голосов
/ 19 января 2010

Текст для флажка в CheckedListBox отображается по умолчанию, чтобы разместить HTML-метку после ввода флажка и установить для атрибута метки «for» идентификатор флажка.

Когда метка обозначает элемент, для которого она «предназначена», нажатие на эту метку заставляет браузер сосредоточиться на этом элементе, а именно это вы видите.

Два варианта - отобразить собственный список с отдельными элементами управления CheckBox и текстом (не как свойство Text CheckBox, так как это делает то же самое, что CheckBoxList), если список статический, или использовать что-то вроде Repeater, если список динамический.

...