【问题标题】:CheckedListBox - How to programmatically ensure that one and only one item can be checked at any given time?CheckedListBox - 如何以编程方式确保在任何给定时间只能检查一项?
【发布时间】:2010-10-23 04:02:43
【问题描述】:

我想在应用程序中使用 CheckedListBox,其中 ListBox 中的每个项目都是我硬盘上的一个文件夹的名称,并且为了在每个文件夹中读取和写入文本文件,我想确保CheckedListBox 中任何时候都只能选择一项(文件夹)

如何通过 C# 中的代码实现这一点?

感谢阅读:-)

编辑\更新 - 2010 年 10 月 22 日 感谢所有花时间回复的人 - 尤其是 Adrift,他们按照要求更新的代码运行良好。

我很欣赏一些评论员对我以这种方式使用选中列表框的看法,但是我觉得它完全符合我的目的,因为我希望毫无疑问地从哪里读取和写入文本文件到。

一切顺利。

【问题讨论】:

  • 当你只允许一个选择时,我不认为复选框是正确的 UI 元素。
  • 您可能应该使用某种单选框,因为普通复选框看起来像多选而不是单选。
  • @CodeInChaos - 谢谢。我正在使用 Visual C# 2010 Express 开发桌面应用程序。我在可用组件列表中看到了 RadioButton,但没有看到 RadioBox - 这只是程序员为一组组合在一起的相关单选按钮说话吗?
  • @The Thing:普通列表框包含一次选择一行的机制。
  • @The Thing:它是 RadioButton,而不是 RadioBox。改用它们,如果你将它们分组在一个 GroupBox 中,那么你可以有许多组 RadioButtons,每个组在给定时间只选择一个 RadioButton。

标签: c# text-files directory checkbox


【解决方案1】:

我同意 cmets 的观点,即当只有一个项目被“选中”时,单选按钮将是常用的 UI 元素,但如果你想在你的 UI 中坚持使用CheckedListBox,你可以尝试这样的事情:

private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
{
    CheckedListBox.CheckedIndexCollection checkedIndices = checkedListBox1.CheckedIndices;

    if (checkedIndices.Count > 0 && checkedIndices[0] != e.Index)
    {
        checkedListBox1.SetItemChecked(checkedIndices[0], false);
    }
}

对于CheckedListBox,您可能还想将CheckOnClick 设置为true

编辑

根据您的评论更新了代码以取消选择未选中的项目。问题是取消选中先前选中的项目会导致事件再次触发。我不知道是否有标准的方法来处理这个问题,但是在下面的代码中,我在调用SetItemCheck 之前分离了处理程序,然后重新附加了处理程序。这似乎是一种处理此问题的干净方法,并且有效。如果我发现有推荐的方法来处理这个问题,我会更新我的答案。

HTH

private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
{
    CheckedListBox.CheckedIndexCollection checkedIndices = checkedListBox1.CheckedIndices;

    if (checkedIndices.Count > 0)
    {
        if (checkedIndices[0] != e.Index)
        {
            // the checked item is not the one being clicked, so we need to uncheck it.  
            // this will cause the ItemCheck event to fire again, so we detach the handler, 
            // uncheck it, and reattach the handler
            checkedListBox1.ItemCheck -= checkedListBox1_ItemCheck;
            checkedListBox1.SetItemChecked(checkedIndices[0], false);
            checkedListBox1.ItemCheck += checkedListBox1_ItemCheck;
        }
        else
        {
            // the user is unchecking the currently checked item, so deselect it
            checkedListBox1.SetSelected(e.Index, false);
        }
    }
}

【讨论】:

  • 谢谢漂流。我已将您上面的代码粘贴到 Form1.cs 中,然后添加了 this.checkedListBox1_ItemCheck += new System.Windows.Forms.ItemCheckEventArgs(this.checkedListBox1_ItemCheck);到 Form1.Designer.cs,但它正在寻找另一个论点 - 我尝试过“对象发送者”和“发送者”,但似乎都不起作用。有什么建议吗?
  • @The Thing,您无需手动将其添加到 Form1.Designer.cs。如果删除添加的行,您可以转到属性表,单击按钮以列出 checkedListBox 的事件,然后在 ItemCheck 事件中,您应该能够从下拉列表中选择此事件处理程序。
  • @The Thing,如果你只是想修复你手动添加的行,它应该是这样的:this.checkedListBox1.ItemCheck += new System.Windows.Forms.ItemCheckEventHandler(this.checkedListBox1_ItemCheck);
  • @Adrift,谢谢,我已经发布了您的代码,现在可以工作了 :-) 但是...我想进一步增强它 - 目前,当我取消选中复选框时,该项目将保持突出显示 -我想删除它,并且只有在勾选时才会突出显示一个项目。我尝试了以下方法-checkedListBox1.SetSelected(checkedIndices[0], false);在大括号内的代码之前和之后 - 之前都无法正常工作,之后给了我一个 IndexOutOfRangeException。我做错了什么?
  • @The Thing,我已经更新了我的答案 - 希望这能满足你的要求 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-01
  • 2011-12-06
  • 1970-01-01
  • 1970-01-01
  • 2016-01-25
相关资源
最近更新 更多