Wednesday 15 May 2013

XAML ListView - scroll SelectedItem to the middle

In the Windows Store app that I recently worked on I used several ListViews to present some data. I had 2 requirements for those lists:
  • The selected item should be always visible
  • In addition it should be displayed in the middle of the list when possible (it's not possible for the first element).
This is what I wanted to achieve:

The first requirement is quite easy to fulfill by using ListView.ScrollIntoView() method. However, this doesn't satisfy the second requirement, as you don't have any control on where exactly the item will appear.

Solution

Instead of working with the ListView directly I worked with the included ScollView control. Here is my method for scrolling with some comments:
public void ScrollToSelected(ListView list, Object selected)
{
    var scrollViewer = list.GetFirstDescendantOfType<ScrollViewer>();
    if (scrollViewer == null) return;

    // Calculate the offset to be used for scrolling.
    // In my case I use ViewPort height, index of the selected item and a fixed value 3 to adjust the result
    double halfList = scrollViewer.ViewportHeight/2;
    int itemIndex = list.Items.IndexOf(selected);
    double scrollOffset = itemIndex - halfList + 3;

    // If offset happens to be bigger than scrollable height use the scrollable height
    // Possible for items from the end of the list
    if (scrollOffset > scrollViewer.ScrollableHeight)
    {
        scrollOffset = scrollViewer.ScrollableHeight;
    }

    // scroll to calculated offset
    scrollViewer.ScrollToVerticalOffset(scrollOffset);
}

No comments: