【问题标题】:Limiting a group of checkboxes to a certain amount of checks将一组复选框限制为一定数量的检查
【发布时间】:2008-09-21 06:20:04
【问题描述】:

我有一组复选框,我只想允许在任何时候检查设定的数量。如果新选中的复选框使计数超过限制,我希望自动取消选中最旧的复选框。这组复选框都使用如下所示的相同事件处理程序。

我已经使用队列实现了该功能,但是当我必须从队列中间删除一个项目时它非常混乱,我认为有一种更优雅的方式。我特别不喜欢将队列转换为列表,只是为了在将列表转换回队列之前调用一种方法。

  • 有没有更好的方法来做到这一点?
  • 像我一样重新挂钩事件处理程序是一个好主意吗?

这是代码。

private Queue<CheckBox> favAttributesLimiter - new Queue<CheckBox>();
private const int MaxFavoredAttributes = 5;

private void favoredAttributes_CheckedChanged(object sender, EventArgs e)
{
    CheckBox cb = (CheckBox)sender;

    if (cb.Checked)
    {
        if (favAttributesLimiter.Count == MaxFavoredAttributes)
        {
            CheckBox oldest = favAttributesLimiter.Dequeue();                  

            oldest.CheckedChanged -= favoredAttributes_CheckedChanged;
            oldest.Checked = false;
            oldest.CheckedChanged += new EventHandler(favoredAttributes_CheckedChanged);
        }

        favAttributesLimiter.Enqueue(cb);

    }
    else // cb.Checked == false
    {                
        if (favAttributesLimiter.Contains(cb))
        {
            var list = favAttributesLimiter.ToList();
            list.Remove(cb);
            favAttributesLimiter=new Queue<CheckBox>(list);
        }
    }
}

编辑:
Chakrit 用更好的 Queue(Of T) 替代品回答了我的实际问题。然而,关于我取消选中复选框的想法实际上是一个坏主意的论点非常有说服力。我将 Chakrit 的答案保留为已接受,但我对其他答案投了赞成票,因为它们在用户眼中提供了更加一致和可用的解决方案。

【问题讨论】:

    标签: .net winforms user-interface


    【解决方案1】:

    以防万一您没有这样想过。

    从可用性的角度来看,大概你有一些文字说“点击不超过 4 个复选框”。

    在这种情况下,为什么不简单地计算复选框的数量,并防止对第 5 个框进行任何更改(当然,直到只有 3 个复选框)。

    【讨论】:

    • 我想过。我无法确定哪种方式对用户来说更烦人,所以我让用户选中他们想要的框,而程序取消选中最旧的框。对于可用性,老实说,我不知道哪种方式更好。
    • 好吧,您的方式有更少的鼠标点击,但您依赖于用户注意到其他框正在被清除。就个人而言,我觉得这更烦人(特别是如果我第一次没有看到它)。
    • 睡在上面之后,我决定不自动取消选中复选框。只有在凌晨 3 点才真正有意义。
    【解决方案2】:

    要问自己一件事:你真的想用复选框来实现这种行为吗?从用户的角度来看,复选框已经具有很好理解的行为,而当一个新的复选框被选中时,一个看似随机的复选框会变为未选中状态,这对普通用户来说可能会非常混乱甚至令人沮丧。

    也许可以考虑类似带有添加/删除按钮的列表框,其中列表的设计为用户提供了一个视觉提示,即最多(例如)四个项目。作为参考,我正在考虑类似于toolbar customizing dialog in IE 的内容。

    也许不是您要寻找的答案,而是需要考虑的问题。

    【讨论】:

      【解决方案3】:

      我认为您正在寻找LinkedList

      使用AddLast 代替EnqueueRemoveFirst 代替Dequeue 并且要删除中间的某些内容,只需使用普通的Remove

      【讨论】:

      • 嗯,删除项目时应该更有效。
      【解决方案4】:

      我之前所做的是有一个这样的多列选择菜单:

                

      选择:已选择 选择-1-空框- 选择-2-空框- 选择-3-空框- 选择-4-空框-

      然后人们可以突出显示“choice-1”并点击右键。突然,第二列将被第一列中的项目填充。然后你可以在添加了3个选项后禁用箭头,并弹出一条消息,“你只能选择三个选项”。与其他选项相比,这更有意义。这对用户来说会容易得多。

      【讨论】:

        【解决方案5】:

        脱钩是个好主意吗? 像我一样的事件处理程序。

        这取决于。

        是 Windows 窗体吗? Windows 窗体运行在 WinAPI 之上,这意味着事件处理程序实际上只是一个由主线程中的消息调度循环调用的函数。因此,这些功能不需要重入并且是“安全的”。

        但是,您必须进行错误处理并捕获任何异常,例如在您的事件处理程序中分配失败,否则您的应用程序将终止。

        【讨论】:

          【解决方案6】:

          如果您要求用户从选项列表中进行选择并限制选择的数量,那么第一选择可能就是主要选择。

          例如选择两个,你永远不会有任何你不选择的东西:

          • 电源
          • 兴奋
          • 小工具
          • 程序员大军。

          你的第一选择是你的首选吗?

          如果您想使用复选框,只需在选中第二个时禁用所有未选中的复选框。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-10-25
            • 1970-01-01
            • 2013-01-05
            • 1970-01-01
            • 1970-01-01
            • 2011-09-20
            • 2013-04-28
            • 1970-01-01
            相关资源
            最近更新 更多