Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deselection on a WPF listbox with extended selection mode

Tags:

c#

wpf

listbox

I have a simple listbox with extended selection mode. Selection works almost perfectly fine like it works in explorer. But deselection doesn't really work all that well. What I want is that when I click on something outside the range of elements in the listbox I want all elements to be deselected. I doesn't seem to behave that way by default and I did a dirty hack involving selectionchanged and mouseup to hack it up. But there has to be a better way. Any ideas?

like image 569
Anders Rune Jensen Avatar asked Jun 03 '09 21:06

Anders Rune Jensen


2 Answers

It isn't that dirty to add in the deselection functionality, and you're on the right track. The main issue is that by default the ListBoxItems inside the ListBox will stretch all the way across, making it pretty tough to not click on one.

Here's an example ListBox that modifies the default ItemContainerStyle so that the items just take up the left side of the list and there is some spacing between the items as well.

<ListBox SelectionMode="Extended"
         Width="200" Mouse.MouseDown="ListBox_MouseDown">
    <ListBox.ItemContainerStyle>
        <Style TargetType="{x:Type ListBoxItem}">
            <Setter Property="Background"
                    Value="LightBlue" />
            <Setter Property="Margin"
                    Value="2" />
            <Setter Property="Padding"
                    Value="2" />
            <Setter Property="Width"
                    Value="100" />
            <Setter Property="HorizontalAlignment"
                    Value="Left" />
        </Style>
    </ListBox.ItemContainerStyle>
    <ListBoxItem >Item 1</ListBoxItem>
    <ListBoxItem >Item 2</ListBoxItem>
    <ListBoxItem >Item 3</ListBoxItem>
    <ListBoxItem >Item 4</ListBoxItem>
</ListBox>

To deselect the selected items we just need to set the SelectedItem to null in the EventHandler. When we click on a ListBoxItem, it will handle the MouseDown/Click etc to set the SelectedItem or modify the SelectedItems. Because of this, and the nature of the RoutedEvents we just handle the MouseDown in the ListBox exactly when we want. When somewhere inside the ListBox is clicked that isn't part of an item.

private void ListBox_MouseDown(object sender, MouseButtonEventArgs e)
{
    (sender as ListBox).SelectedItem = null;
}
like image 145
rmoore Avatar answered Sep 30 '22 14:09

rmoore


I've used myListBox.SelectedItems.Clear(). Most selected items collections are read-only, but not the list boxes.

like image 45
Geoff Cox Avatar answered Sep 30 '22 15:09

Geoff Cox