简体   繁体   English

Winforms checkedlistbox检查一个项目

[英]Winforms checkedlistbox check one item

I have a CheckedListBox control on my form, and I want the user to only be able to check one item at a time within this list (so effectively I'd want something that would mimic a "RadioListBox"). 我的表单上有一个CheckedListBox控件,我希望用户只能在此列表中一次检查一个项目(因此我有效地想要一些模仿“RadioListBox”的东西)。

Is this possible to do with a CheckedListBox or would I have to improvise doing it some other way? 这可能与CheckedListBox还是我必须通过其他方式即兴创作?

The CheckedListBox is populated on the form load by loading items from a database, in case that matters. 如果重要,则通过从数据库加载项来填充表单加载中的CheckedListBox

Thanks 谢谢

Edit 编辑

I think I should clarify, I am not looking to limit the amount a user can SELECT (ie the SelectionMode property), rather how many they can CHECK. 我想我应该澄清一下,我不打算限制用户可以选择的数量(即SelectionMode属性),而不是他们可以检查多少。

You could do it by adding an event check on CheckedListBox for ItemCheck and use function like this: 您可以通过在CheckedListBox上为ItemCheck添加事件检查来实现,并使用如下函数:

    private static bool checkIfAllowed(CheckedListBox listBox) {
        if (listBox.CheckedItems.Count > 0) {
            return false;
        }
        return true;
    }

Then in the event you would have like: 那么在你想要的情况下:

  if (checkIfAllowed) { 
     ...
  } else {

  }

Additionally you could improve this by adding another function/method that will uncheck all items before allowing item to be checked. 此外,您可以通过添加另一个功能/方法来改进这一点,该功能/方法将在允许检查项目之前取消选中所有项目。 So when users click some checkbox all other checkboxes are unchecked. 因此,当用户单击某个复选框时,将取消选中所有其他复选框。

To uncheck all checked items just use: 要取消选中所有选中的项目,只需使用:

    private static void uncheckAll(CheckedListBox listBox) {
        IEnumerator myEnumerator;
        myEnumerator = listBox.CheckedIndices.GetEnumerator();
        int y;
        while (myEnumerator.MoveNext() != false) {
            y = (int)myEnumerator.Current;
            listBox.SetItemChecked(y, false);
        }
    }

So in ItemCheck event you would have to run uncheckAll(yourListBox) first and then simply let the item be checked. 因此,在ItemCheck事件中,您必须先运行uncheckAll(yourListBox) ,然后只需检查该项。

Edit: I've tested it with following code and it works. 编辑:我已经使用以下代码测试它,它的工作原理。 Without the if it throws exception. 没有if它抛出异常。

    private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e) {
        if (e.NewValue == CheckState.Checked) {
            IEnumerator myEnumerator;
            myEnumerator = checkedListBox1.CheckedIndices.GetEnumerator();
            int y;
            while (myEnumerator.MoveNext() != false) {
                y = (int)myEnumerator.Current;
                checkedListBox1.SetItemChecked(y, false);
            }
        }

    }

尝试设置.SelectionMode = SelectionMode.One属性。

This code is could be much more simple, requires one variable. 这段代码可以简单得多,需要一个变量。 Every time you will check a new box, it will uncheck the last one, leading to the fact that there won't be two checked items or more checked at the time. 每次你检查一个新的盒子时,它都会取消选中最后一个盒子,导致当时没有两个被检查的项目或更多。 Make sure the property SelectionMode = SelectionMode.One; 确保属性SelectionMode = SelectionMode.One; is set as mentioned. 如上所述设置。

    private int lastCheck = -1;
    private void CheckListBox_IndexChanged(object sender, EventArgs e) {
        int toUncheck = lastCheck;
        if (toUncheck != -1)
            CheckListBox.SetItemChecked(toUncheck, false);
        lastCheck = CheckListBox.SelectedIndex;
        CheckListBox.SetItemChecked(lastCheck, true);
    }

Or alternativly you could set lastCheck to the default checked box if required, do this by: 或者,如果需要,您可以将lastCheck设置为默认复选框,通过以下方式执行此操作:

    private void FormFoo_Load(object sender, EventArgs e) {
        CheckListBox.SelectedIndex = 0;
        lastCheck = CheckListBox.SelectedIndex;
    }

and then the rest of the code that I mentioned above comes below. 然后我在上面提到的其余代码如下。

Notice*: I've used lastCheck = **CheckListBox.SelectedIndex;** to support keyboard moving, just in case. 注意*:我使用了lastCheck = **CheckListBox.SelectedIndex;**来支持键盘移动,以防万一。

I had to do something similar to select a single user from a massive list. 我必须做类似的事情从大量列表中选择一个用户。 There isn't a RadioListBox to speak of, so I just coded it manually... 没有RadioListBox可以说,所以我只是手动编码...

Sorry it's in VB, I just pasted it in, the logic is the same. 对不起,在VB中,我只是粘贴它,逻辑是一样的。

Private m_NoFire As Boolean = False

Private Sub lstSource_ItemCheck( _
        ByVal sender As Object, _
        ByVal e As System.Windows.Forms.ItemCheckEventArgs) Handles lstSource.ItemCheck

    'When the checked state is set programatically,
    'this event will still fire and cause the loop
    'to run - infinatly. This line prevents that.
    If m_NoFire Then Exit Sub
    m_NoFire = True

    'Ensure only one item is selected
    For i As Integer = 0 To lstSource.Items.Count - 1
        If Not lstSource.SelectedIndex = i Then
            lstSource.SetItemChecked(i, False)
        End If
    Next

    m_NoFire = False

End Sub '-- lstSource_ItemCheck

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM