как проверить только один элемент в checklistbox

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

private void CLSTVariable_ItemCheck(object sender, ItemCheckEventArgs e)
{
  // Local variable
  int ListIndex;

  CLSTVariable.ItemCheck -= CLSTVariable_ItemCheck;

  for (ListIndex = 0; 
       ListIndex < CLSTVariable.Items.Count; 
       ListIndex++)
  {        
    // Unchecked all items that is not currently selected
    if (CLSTVariable.SelectedIndex != ListIndex)
    {
      // set item as unchecked
      CLSTVariable.SetItemChecked(ListIndex, false);
    } // if
    else
    {
      // set selected item as checked
      CLSTVariable.SetItemChecked(ListIndex, true);
    }
  } // for
  CLSTVariable.ItemCheck += CLSTVariable_ItemCheck;  
}

этот код работает нормально.

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


person Shashi Jaiswal    schedule 10.03.2011    source источник
comment
Почему бы вам не использовать RadioButtonList, если вы хотите выбрать только один элемент? Используйте пилу, чтобы пилить, и отвертку, чтобы закручивать винты...   -  person Bazzz    schedule 10.03.2011
comment
Базз, действительно. Но я должен сказать, что я «часто» нахожу такой способ решения с одним тегом и одним флажком. Любой, у кого есть веская причина, почему, пожалуйста, отметьте это для меня! (Кроме косметической причины, которую я могу принять).   -  person Independent    schedule 10.03.2011
comment
Я согласен с Баззом. Неправильный инструмент для работы. Ключевым аспектом UX является то, что пользователь хорошо знаком с некоторыми подсказками пользовательского интерфейса. Годы наблюдения за флажками означают, что они ожидают, что смогут отметить несколько. Если вы навязываете отметку одному флажку, это очень неприятно для пользователя.   -  person Ray Booysen    schedule 10.03.2011
comment
@Ray Booysen: Согласен, и, кроме того, движение против течения означает, что вы в конечном итоге столкнетесь с трудностями кодирования, которые приводят к тому, что вы задаете вопросы на StackOverflow :)   -  person Bazzz    schedule 10.03.2011


Ответы (4)


Я согласен с комментаторами выше - вам следует подумать об использовании радиокнопок. Но если вам действительно нужен CheckedListBox, используйте этот обработчик событий ItemChecked:

private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
{
    if (checkedListBox1.CheckedItems.Count == 1)
    {
        Boolean isCheckedItemBeingUnchecked = (e.CurrentValue == CheckState.Checked);
        if (isCheckedItemBeingUnchecked)
        {
            e.NewValue = CheckState.Checked;
        }
        else
        {
            Int32 checkedItemIndex = checkedListBox1.CheckedIndices[0];
            checkedListBox1.ItemCheck -= checkedListBox1_ItemCheck;
            checkedListBox1.SetItemChecked(checkedItemIndex, false);
            checkedListBox1.ItemCheck += checkedListBox1_ItemCheck;
        }

        return;
    }
}
person Loki Kriasus    schedule 10.03.2011
comment
Я думаю, вам нужно изменить e.NewValue = CheckState.Checked; на e.NewValue = CheckState.Unchecked;. В противном случае вы не сможете снять отметку с уже выбранных элементов. - person Christian Junk; 17.07.2012
comment
@ChristianJunk, это то, чего хотел автор вопроса - всегда должен быть проверен хотя бы один элемент. - person Loki Kriasus; 17.07.2012

Ну, это был ответ мне! Мне не удалось заставить приведенный выше код работать в файле checkedListBox1_ItemCheck. Мне пришлось изменить его часть и включить в событие checkedListBox1_SelectedIndexChanged. Но я не мог полностью удалить исходный код. Вот что я добавил...

private void checkedListBox1_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (checkedListBox1.CheckedItems.Count > 1)
        {
            Int32 checkedItemIndex = checkedListBox1.CheckedIndices[0];
            checkedListBox1.ItemCheck -= checkedListBox1_ItemCheck;
            checkedListBox1.SetItemChecked(checkedItemIndex, false);
            checkedListBox1.ItemCheck += checkedListBox1_ItemCheck;
        }
    }

В основном, если у вас установлено более 1 флажка, переключите последний на новый. Мне любопытно, почему исходный код не работал. И почему он должен быть там, чтобы мой новый код работал? Спасибо.

person topofsteel    schedule 24.04.2012

Я нашел этот код, он работает так хорошо

private void chkboxmov_ItemCheck(object sender, ItemCheckEventArgs e)
{
    for (int ix = 0; ix < chkboxmov.Items.Count; ++ix)
        if (ix != e.Index)
            chkboxmov.SetItemChecked(ix, false);
}
person hank    schedule 13.01.2014

"всегда следует проверять хотя бы один элемент"

Текущее решение (последнее) позволяет отмечать элементы. Если ваша цель — постоянно выбирать только один элемент, используйте его как событие MouseUp,

    private void ChklbBatchType_MouseUp(object sender, MouseEventArgs e)
    {
        int index = ((CheckedListBox)sender).SelectedIndex;
        for (int ix = 0; ix < ((CheckedListBox)sender).Items.Count; ++ix)
            if (index != ix) { ((CheckedListBox)sender).SetItemChecked(ix, false);   }
              else ((CheckedListBox)sender).SetItemChecked(ix, true);
    }
person Goodies    schedule 04.12.2019