I have a text box where I want to limit the number of selected items to MaxSelection. The desired behaviour is that once MaxSelection items are selected any futher selections are ignored. (Thus this question is different from "limit selections in a listbox in vb.net").
I have an event handler for the SelectedIndexChanged event for the list box that attempts to accomplish this. If the user uses Ctrl-click to select the (MaxSelection+1)th item, the selection is reverted to the previous selection.
The problem is when the user selects an item and then Shift-clicks an item down the list that is MaxSelection+1 items further down the list. In this case, more than one SelectedIndexChanged event is raised: one for the Shift-click which selects the item that was Shift-clicked, and one to select all the items between the original selection and the Shift-clicked selection. The first of these events allows the user to select the Shift-clicked item (which is technically correct), then the second event reverts the selection to the selection as it was after the first event (which will be the originally selected item and the Shift-clicked item). What is desired is that the code would revert the selection to the selection before the first event (which is only the originally selected item).
Is there any way to retain the selection before the Shift-click?
Thanks, Rob
Here's the SelectedIndexChanged event handler:
void ChildSelectionChanged(object sender, EventArgs e)
{
ListBox listBox = sender as ListBox;
//If the number of selected items is greater than the number the user is allowed to select
if ((this.MaxSelection != null) && (listBox.SelectedItems.Count > this.MaxSelection))
{
//Prevent this method from running while reverting the selection
listBox.SelectedIndexChanged -= ChildSelectionChanged;
//Revert the selection to the previous selection
try
{
for (int index = 0; index < listBox.Items.Count; index++)
{
if (listBox.SelectedIndices.Contains(index) && !this.previousSelection.Contains(index))
{
listBox.SetSelected(index, false);
}
}
}
finally
{
//Re-enable this method as an event handler for the selection change event
listBox.SelectedIndexChanged += ChildSelectionChanged;
}
}
else
{
//Store the current selection
this.previousSelection.Clear();
foreach (int selectedIndex in listBox.SelectedIndices)
{
this.previousSelection.Add(selectedIndex);
}
//Let any interested code know the selection has changed.
//(We do not do this in the case where the selection would put
//the selected count above max since we revert the selection;
//there is no net effect in that case.)
RaiseSelectionChangedEvent();
}
}