CheckedListBox Control - проверка флажка только при щелчке по фактическому флажку

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

Ответ 1

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

Ответ 2

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

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

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

Ответ 3

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

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

Ответ 4

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

Когда ярлык обозначает элемент, который он "для", щелчок на этой метке указывает браузеру сосредоточиться на этом элементе, что вы видите.

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

Ответ 5

Попробуйте это. Объявить iLastIndexClicked как переменную типа на уровне формы.

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