I have a group of checkboxes that I only want to allow a set amount to be checked at any one time. If the newly checked checkbox pushes the count over the limit, I'd like the oldest checkbox to be automatically unchecked. The group of checkboxes all use the same event handler shown below.
I have achieved the functionality with a Queue, but it's pretty messy when I have to remove an item from the middle of the queue and I think there's a more elegant way. I especially don't like converting the queue to a list just to call one method before I convert the list back to a queue.
- Is there a better way to do this?
- Is it a good idea to unhook are rehook the event handlers like I did.
Here's the code.
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);
}
}
}
Edit:
Chakrit answered my actual question with a better replacement for Queue(Of T). However, the argument that my idea of unchecking boxes was actually a bad idea was quite convincing. I'm leaving Chakrit's answer as accepted, but I've voted up the other answers because they're offering a more consistent and usable solution in the eyes of the user.