【问题标题】:Winforms checkedlistbox check one itemWinforms 勾选列表框勾选一项
【发布时间】:2011-05-22 04:22:54
【问题描述】:

我的表单上有一个CheckedListBox 控件,并且我希望用户一次只能检查此列表中的一个项目(因此我想要一些模仿“RadioListBox”的东西)。

这可以用CheckedListBox 来做吗,还是我必须即兴发挥它的其他方式?

CheckedListBox 在表单加载时通过从数据库加载项目来填充,以防万一。

谢谢

编辑

我想我应该澄清一下,我并不是要限制用户可以选择的数量(即 SelectionMode 属性),而是他们可以检查的数量。

【问题讨论】:

  • 那么为什么要使用选中的列表框。你可以只使用一个简单的列表框。
  • 不幸的是,用户特别要求能够“检查”。如果没有证明有一种简单的方法可以限制一次可以检查的项目数量,那么我将按照您所说的那样使用普通的列表框。
  • 使用 ComboBox 代替。 DropDownStyle = 如果你真的想要一个列表,那就简单。

标签: c# winforms .net-3.5


【解决方案1】:

此代码可能要简单得多,只需要一个变量。 每次选中一个新框时,它都会取消选中最后一个框,从而导致当时不会有两个或更多已选中的项目被选中。 确保按上述设置属性SelectionMode = SelectionMode.One;

    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);
    }

或者,如果需要,您可以将 lastCheck 设置为默认复选框,通过以下方式执行此操作:

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

然后我上面提到的其余代码在下面。

注意*:我使用lastCheck = **CheckListBox.SelectedIndex;** 来支持键盘移动,以防万一。

【讨论】:

    【解决方案2】:

    您可以通过在 CheckedListBox 上为 ItemCheck 添加事件检查并使用如下函数来做到这一点:

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

    如果您愿意:

      if (checkIfAllowed) { 
         ...
      } else {
    
      }
    

    此外,您可以通过添加另一个功能/方法来改进这一点,该功能/方法将在允许检查项目之前取消选中所有项目。因此,当用户单击某个复选框时,所有其他复选框都未选中。

    要取消选中所有选中的项目,只需使用:

        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);
            }
        }
    

    因此,在 ItemCheck 事件中,您必须先运行 uncheckAll(yourListBox),然后简单地检查项目。

    编辑: 我已经使用以下代码对其进行了测试,并且可以正常工作。没有 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);
                }
            }
    
        }
    

    【讨论】:

    • 感谢 Madboy,但是 uncheckAll 方法会导致 StackOverflowException 被抛出 - 每次你可以 SetItemChecked 触发 ItemChecked 事件,这意味着 uncheckAll 也被连续触发。除非我忘记做某事?
    【解决方案3】:

    我不得不做一些类似的事情来从一个庞大的列表中选择一个用户。没有 RadioListBox 可言,所以我只是手动编码...

    不好意思是在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
    

    【讨论】:

    • KMan 刚刚发布了一个更好的方法。尽管如此,这段代码已经在项目中使用了大约 5 年,我现在没有改变它:D
    • @KMan 重新考虑,看看那个链接,我认为它不会限制检查,只有选择。
    【解决方案4】:

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

    【讨论】:

    • 这只能让我一次选择一个项目(即突出显示),它不控制随时可以检查多少项目。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-15
    • 1970-01-01
    • 2019-12-07
    • 2017-10-17
    相关资源
    最近更新 更多