将一组复选框限制为一定数量的复选框
我有一组复选框,我只想允许一次检查设定的金额。如果新选中的复选框使计数超过了限制,我希望最旧的复选框被自动取消选中。复选框组全部使用如下所示的相同事件处理程序。
我已经使用Queue实现了功能,但是当我不得不从队列中间删除项目时,这很混乱,我认为这是一种更为优雅的方法。我特别不喜欢将队列转换为列表,只是想在将列表转换回队列之前调用一种方法。
- 有一个更好的方法吗?
- 像我一样,摘机并重新挂起事件处理程序是否是一个好主意。
这是代码。
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的答案留为接受,但我投票赞成其他答案,因为它们在用户眼中提供了更一致和可用的解决方案。
解决方案
我认为我们正在寻找LinkedList。
使用AddLast
代替Enqueue
和RemoveFirst
代替Dequeue
,并且在中间删除某些东西,只需使用普通的Remove
。
以防万一我们还没有想到这种方式。
从可用性的角度来看,大概我们有一些文字,例如"单击不超过4个复选框"。
在这种情况下,为什么不简单地对复选框的数量进行计数,并防止对第5个复选框进行任何更改(当然,只有3个复选框)。
问自己一件事:我们是否真的想通过复选框实现这种行为?从用户的角度来看,复选框的行为已经得到了很好的理解,并且当一个新的复选框被选中时,一个看上去随机的复选框被取消选中可能会使普通用户感到困惑甚至沮丧。
也许考虑使用带有添加/删除按钮的列表框之类的东西,其中列表的设计为用户提供了视觉提示,即最多(例如)四个项目。作为参考,我在考虑IE中工具栏自定义对话框的思路。
也许不是我们要找的答案,而是要考虑的问题。
我之前所做的是有一个像这样的多列选择菜单:
<---->
选择:选择的选项1-空的盒子-选择的2-空的盒子-选择的3-空的盒子-选择的4-空的盒子-
然后,人们可以突出显示" choice-1",然后单击右键。突然,第二列将由第一列中的项目填充。然后,我们可以在添加3个选项后禁用箭头,然后弹出一条消息,说"我们只能选择3个选项"。与其他选项相比,这更有意义。对于用户而言,这将容易得多。
如果我们要求用户从选项列表中进行选择并限制选择的数量,则第一选择很可能是主要选择。
例如选择两个,我们将永远不会拥有任何我们不会选择的东西:
- 钱
- 力量
- 性别
- 激动
- 小工具
- 编码军。
首选是首要选择吗?
如果要使用复选框,只需在选中第二个复选框时禁用所有未选中的复选框即可。
Is it a good idea to unhook are rehook the event handlers like I did.
那要看。
是Windows窗体吗? Windows窗体在WinAPI之上运行,这意味着事件处理程序实际上只是主线程中的消息分发循环调用的函数。因此,这些功能不需要重新输入,并且是"安全的"。
但是,我们必须执行错误处理,并在事件处理程序中捕获任何异常,例如分配失败,否则应用程序将终止。