waltmagic
waltmagic

Reputation: 642

CheckedListBox Only One Checked But Keep Last

I am having some difficulty getting a CheckedListBox to behave the way I want it to. What I am trying to accomplish is getting a CheckedListBox with the first box checked on PageLoad. I want only one checkbox checked at any given time but I also don't want the user to uncheck the last checked box. I can do one or the other but I can't seem to do both.

Here is some code snippets that I have used to accomplish the task of having only one checkbox checked. The problem with these are the last selection can be unchecked where there are no checkboxes checked.

1st Snippet:

        if(e.NewValue == CheckState.Checked)
        {
            // Uncheck the other items
            for (int i = 0; i < defCheckedListBox.Items.Count; i++)
            {
                if (e.Index != i)
                {
                    this.defCheckedListBox.SetItemChecked(i, false);
                }
            }
        }

2nd Snippet

        // Ensure that we are checking an item
        if (e.NewValue != CheckState.Checked)
        {
            return;
        }

        // Get the items that are selected
        CheckedListBox.CheckedIndexCollection selectedItems = this.defCheckedListBox.CheckedIndices;

        // Check that we have at least 1 item selected
        if (selectedItems.Count > 0)
        {
            // Uncheck the other item
            this.defCheckedListBox.SetItemChecked(selectedItems[0], false);
        }

Here is what I have used to prevent the last checked box to be "unchecked"

        if (laborLevelDefCheckedListBox.CheckedItems.Count == 1)
        {
            if (e.CurrentValue == CheckState.Checked)
            {
                e.NewValue = CheckState.Checked;
            }
        }

I know this has got to be simple but I think because I've had a long week and I have looked at this too long it is just not coming to me. Any help with this is super appreciated! If I solve this over the weekend I will be sure to post my solution. BTW Happy Holidays to those here in the States :)

Upvotes: 1

Views: 1714

Answers (2)

Kevin R. Durler
Kevin R. Durler

Reputation: 1

// Use CheckBoxList Event
private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)  {
    // Stops DeInitialize Event
    checkedListBox1.ItemCheck -= checkedListBox1_ItemCheck;
    // Get the new value old value my be in Indeterminate State
    checkedListBox1.SetItemCheckState(e.Index, e.NewValue);
    // Start ReInitialize Event
    checkedListBox1.ItemCheck += checkedListBox1_ItemCheck;
}

Upvotes: 0

petelids
petelids

Reputation: 12815

Chris makes a good point in the comments that this feels like you are re-inventing radio buttons but you are almost there with the code you have posted if you really want it to work with a CheckedListBox. I have adapted the code from your 1st Snippet which I think does the trick:

//remove the event handler so when we change the state of other items the event
//isn't fired again.
defCheckedListBox.ItemCheck -= defCheckedListBox_ItemCheck;

if (e.NewValue == CheckState.Checked)
{
    // Uncheck the other items
    for (int i = 0; i < defCheckedListBox.Items.Count; i++)
    {
        if (e.Index != i)
        {
            this.defCheckedListBox.SetItemChecked(i, false);
        }
    }
 }
 else
 {
     //the state was not checked.
     //as only one item can ever be Checked inside the event
     //handler the state of not checked is invalid for us; set the state back to Checked.
     e.NewValue = CheckState.Checked;
 }

 //re-add the event handler 
 defCheckedListBox.ItemCheck += defCheckedListBox_ItemCheck;

Essentially the only new parts are the else where we reset the state if the state was not Checked and the removing and re-adding of the event to prevent it firing again when we manually set the state of other items (this could be handled with a global bool if you prefer).

Upvotes: 2

Related Questions