Как потребовать, чтобы в CheckedListBox был выбран хотя бы один элемент - PullRequest
3 голосов
/ 05 мая 2010

С CheckListBox в VB.NET в VS2005, как сделать обязательным, чтобы был выбран хотя бы один элемент?

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

Каков наилучший способ справиться с проверочной частью этого сценария? Когда пользователь должен поставить галочку в одном из полей?

Ответы [ 6 ]

5 голосов
/ 10 мая 2010

Любая идея - предотвратить снятие отметки с последнего проверенного элемента пользователем или проверить, что хотя бы один элемент проверен перед продолжением - довольно проста для реализации.

Как запретить пользователю снимать отметку с последнего проверенного элемента

1. Убедитесь, что хотя бы один элемент отмечен для начала (например, в событии Load вашей формы) :

Private Sub frm_Load(ByVal sender As Object, ByVal e As EventArgs)
    clb.SetItemChecked(0, True) ' whatever index you want as your default '
End Sub

2. Добавьте некоторую простую логику в ваш ItemCheck обработчик событий :

Private Sub clb_ItemCheck(ByVal sender As Object, ByVal e As ItemCheckEventArgs)
    If clb.CheckedItems.Count = 1 Then ' only one item is still checked... '
        If e.CurrentValue = CheckState.Checked Then ' ...and this is it... '
            e.NewValue = CheckState.Checked ' ...so keep it checked '
        End If
    End If
End Sub

Как проверить, что хотя бы один элемент отмечен

Private Sub btn_Click(ByVal sender As Object, ByVal e As EventArgs)
    ' you could also put the below in its own method '
    If clb.CheckedItems.Count < 1 Then
        MsgBox("You must check at least one item.")
        Return
    End If

    ' do whatever you need to do '
End Sub
2 голосов
/ 13 мая 2010

Это решение должно быть близко. Не 100%, нет простого способа узнать, что элементы были добавлены в пустой список. Добавьте новый класс в ваш проект и вставьте код, показанный ниже. Компиляция. Перетащите новый элемент управления из верхней части панели инструментов на форму. Дополнительный код не требуется.

Public Class MyCheckedListBox
    Inherits CheckedListBox

    Protected Overrides Sub OnEnter(ByVal e As System.EventArgs)
        REM Ensure at least one item is checked
        MyBase.OnEnter(e)
        If Me.CheckedIndices.Count = 0 AndAlso Me.Items.Count > 0 Then
            Me.SetItemChecked(0, True)
        End If
    End Sub

    Protected Overrides Sub OnItemCheck(ByVal e As ItemCheckEventArgs)
        REM Prevent unchecking last item
        If Me.CheckedIndices.Count <= 1 AndAlso e.NewValue = CheckState.Unchecked Then e.NewValue = CheckState.Checked
        MyBase.OnItemCheck(e)
    End Sub
End Class

Опциональное дополнительное переопределение, обеспечивающее проверку элемента при первом появлении формы:

Protected Overrides Sub OnHandleCreated(ByVal e As System.EventArgs)
    MyBase.OnHandleCreated(e)
    If Me.CheckedIndices.Count = 0 AndAlso Me.Items.Count > 0 Then
        Me.SetItemChecked(0, True)
    End If
End Sub
2 голосов
/ 05 мая 2010

Можно, но пользователь всегда может снять галочку.

Я бы сделал это при отправке, циклически просматривая элементы-флажки и следя за тем, чтобы хотя бы один из них был отмечен (прервите цикл после того, как ваше требование будет выполнено, не нужно обрабатывать остальную часть списка). )

Если проверка не пройдена, сделать видимым пользовательский валидатор. Валидаторы обязательных полей не работают с полями Check List, но вы можете увидеть, как они реализованы здесь:

http://www.codeproject.com/KB/webforms/Validator_CheckBoxList.aspx

1 голос
/ 05 мая 2010

Перехватите событие ItemCheck и убедитесь, что последний флажок снят:

    private void Form1_Load(object sender, EventArgs e)
    {
        checkedListBox1.SetItemChecked(0, true);
        checkedListBox1.ItemCheck += checkedListBox1_ItemCheck;
    }

    private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
    {
        if (CountChecked() == 1 &&
            e.NewValue == CheckState.Unchecked &&
            e.CurrentValue == CheckState.Checked)
        {
            checkedListBox1.SetItemChecked(0, true);
        }
    }

    private int CountChecked()
    {
        int count = 0;
        for (int i = 0; i < checkedListBox1.Items.Count; i++)
        {
            if (checkedListBox1.GetItemChecked(i) == true)
                count++;
        }
        return count;
    }

Обновлено: необходимо выполнить асинхронный вызов для возврата состояния проверки элемента.

    private delegate void SetItemCallback(int index);

    private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
    {
        if (checkedListBox1.CheckedIndices.Count == 1 &&
            e.NewValue == CheckState.Unchecked &&
            e.CurrentValue == CheckState.Checked)
        {
            int index = checkedListBox1.CheckedIndices[0];
            // Initiate the asynchronous call.
            SetItemCallback d = new SetItemCallback(this.SetItem);
            d.BeginInvoke(index, null, null);
        }
    }
    private void SetItem(int index)
    {
        if (this.checkedListBox1.InvokeRequired)
        {
            SetItemCallback d = new SetItemCallback(SetItem);
            this.Invoke(d, new object[] { index });
        }
        else
        {
            checkedListBox1.SetItemChecked(index, true);
        }
    }
0 голосов
/ 16 мая 2010

Я бы использовал событие ItemCheck для установки Button.Enabled = false, когда не проверен хотя бы один элемент, и Button.Enabled = true, когда проверен хотя бы один элемент (при условии, что кнопка Ok или что-то еще так).

0 голосов
/ 10 мая 2010

Предложение по сценарию проверки:

  • Если ваша winform имеет кнопку Отправить / Сохранить, я бы хотел, чтобы приложение показывало ошибку при нажатии кнопки (при условии, что есть ярлык, указывающий, что должен быть выбран хотя бы один элемент). Сообщение об ошибке не обязательно должно быть MessageBox, это может быть красная метка, показывающая описание ошибки в самой форме

  • Если нет кнопок, которые можно удерживать, выполните проверку, как если бы пользователи нажимали на элементы. Используя событие ItemCheck, проверьте, проверен ли хотя бы один элемент. Если нет, покажите метку ошибки.

Код:

private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
{
    if (checkedListBox1.CheckedIndices.Count == 1 &&
        e.NewValue == CheckState.Unchecked &&
        e.CurrentValue == CheckState.Checked)
    {
        //Show error label in red
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...