Valo
Valo

Reputation: 2048

ListBox with extended selection mode, bring selected in view

I am writing this only to help others who might face the same issue. I have a list box with selection mode set to extended. In a certain user story of my app I needed to deselect all selected items, select programatically just one item and bring it in view. OK, there are plenty of samples out there but for some reason my code was not working: if the selected item was hidden, the SelectionChanged event was comming with empty Added items collection. The difference between my case and the samples out there is the selection mode...

Upvotes: 0

Views: 881

Answers (1)

Valo
Valo

Reputation: 2048

After half a day digging, in some seemingly unrelated case some good man hinted the "very intuitive" solution: set the list box property ScrollViewer.CanContentScroll to False - why I didn't think of that first...? Now pick your favorite approach and it will do what it is supposed to. FYI here is my solution:

<ListBox Name="listUsers"
         SelectionMode="Extended"
         ScrollViewer.CanContentScroll="False"> <!-- more properties, template, ItemContainerStyle, etc.... -->
    <i:Interaction.Behaviors>
        <b:ScrollSelectedListBoxItemIntoViewBehavior />
    </i:Interaction.Behaviors>
<ListBox>

and here is the event handler wrapped in a behavior:

public class ScrollSelectedListBoxItemIntoViewBehavior : Behavior<ListBox>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.SelectionChanged += AssociatedObject_SelectionChanged;
    }

    protected override void OnDetaching()
    {
        AssociatedObject.SelectionChanged -= AssociatedObject_SelectionChanged;
        base.OnDetaching();
    }

    void AssociatedObject_SelectionChanged(
        object sender,
        SelectionChangedEventArgs e)
    {
        if (e.AddedItems == null || e.AddedItems.Count == 0)
            return;

        var listBoxItem = AssociatedObject.ItemContainerGenerator.ContainerFromItem(e.AddedItems[0]) as ListBoxItem;

        if (listBoxItem != null)
            listBoxItem.BringIntoView();
    }
}

Hope this will save some time to another unhappy soul out there or someone with more experience will suggest even better solution.

Upvotes: 2

Related Questions