CheckedListBox Control — установка флажка только при щелчке фактического флажка

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


person Oxymoron    schedule 19.01.2010    source источник
comment
вы можете использовать дополнительную метку, просто список флажков, а затем создавать метки, .. это не очень приятное решение, но оно работает :›   -  person Tyzak    schedule 19.01.2010
comment
Может я что-то упускаю. Что происходит сейчас, когда вы ставите галочку? Ничего такого? Он что-то проверяет по умолчанию? Что происходит, что вы хотите остановить?   -  person hunter    schedule 19.01.2010
comment
Я хочу, чтобы флажок устанавливался только тогда, когда я щелкаю по самому полю, а не по строке. Представьте, что это выглядит так: [ ] Item1 В настоящее время флажок устанавливается при щелчке по всему элементу, но я этого не хочу. Я хочу, чтобы на него нажимали только тогда, когда я нажимаю на само поле, а не на описательный текст рядом с ним.   -  person Oxymoron    schedule 19.01.2010


Ответы (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;
        }
    }
}
person Dynami Le Savard    schedule 20.01.2010
comment
Да, как я уже сказал в OP, я тоже думал о чем-то подобном, но, поскольку это не очень хорошо, я начал искать альтернативы :) - person Oxymoron; 20.01.2010
comment
Спасибо, это просто работает! Возможны некоторые оптимизации, но идея работает! - person nightcoder; 29.04.2010

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

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

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

person Wilfred    schedule 02.01.2011

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

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

person ryan    schedule 10.02.2012

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

CheckedBoxList.CheckOnClick

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

person Francesco    schedule 19.01.2019

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

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

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

person Kevin Gorski    schedule 19.01.2010
comment
Это не веб-форма, а винформа :) Но я понял ваш дрейф. Фокусировка в порядке, и на самом деле то, что я хочу, я просто не хочу, чтобы флажок устанавливался при нажатии на сам элемент. Кажется, я собираюсь возиться с пользовательским элементом управления :) - person Oxymoron; 19.01.2010
comment
Хорошо, трудно сказать, когда в качестве тегов были только c# и CheckedListBox. Я пошел дальше и добавил winforms. - person Kevin Gorski; 20.01.2010

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

person George Butler    schedule 09.01.2018