Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Let ListView scroll to selected item

I have a WinRT/C#/XAML app with a view that has a vertical ListView of items. Depending on the amount of items the ListView shows a vertical scrollbar. Here's the XAML definition:

<UserControl.Resources>
    <CollectionViewSource
        x:Name="myViewSource"
        Source="{Binding myViewModel.Items}" />
</UserControl.Resources>
...
<ListView
    x:Name="myListView"
    ItemsSource="{Binding Source={StaticResource myViewSource}}"
    SelectedItem="{Binding SelectedItem, Mode=TwoWay}">
</ListView>

Now everytime I navigate to this view, the selected item of the ListView is chosen by setting the databound SelectedItem property in the view model from code behind (OnNavigatedTo). My problem: the ListView doesn't scroll automatically to this selected item. The scrollbar remains at the top of the ListView and the user has to scroll manually to see the selected item.

I tried to execute myListView.ScrollIntoView(MyViewModel.SelectedItem); after setting the SelectedItem in the code behind (in OnNavigatedTo), but it doesn't work. The scrollbar remains at the top.

I'm aware of this thread on SO: Scroll WinRT ListView to particular group . This seems to be a similar problem. But when I walk the visual tree of the ListView manually or with the WinRT XAML Toolkit, it doesn't find a ScrollViewer (returns null instead).

like image 919
Matthias Avatar asked Aug 24 '12 11:08

Matthias


People also ask

How to scroll to the specific item in a list?

In this example, we will create a List using Scroll View to hold the data, a TextInput and a button to take the index as input and scroll to the item. How to Scroll to the Specific item? 1. To scroll to the specific item first we will make a blank array to store the X and Y coordinates of the item. 2.

Where does the scrollbar go in a listview?

The scrollbar remains at the top of the ListView and the user has to scroll manually to see the selected item. I tried to execute myListView.ScrollIntoView (MyViewModel.SelectedItem); after setting the SelectedItem in the code behind (in OnNavigatedTo ), but it doesn't work. The scrollbar remains at the top.

How do I scroll to the 9th item in the list view?

For example: There are 10 items in the list view and only the first 5 are visible. A function selects the 9th item and the list view should automatically scroll to the 9th item.

How to scroll to random items in a listview?

In case the heights of the items are different and not set, move on to another method in this article. This example app contains a ListView with 100 items and a floating button. When the user presses the floating button, the view will scroll to a random item (you can replace it with a constant number if you want to).


1 Answers

Thanks to Filip I noticed that calling ScrollIntoView() in OnNavigatedTo() was too early, because the ListView control is not loaded yet in this place.

The first solution idea was to bind the Loaded event of the ListView:

myListView.Loaded += (s, e) => 
    myListView.ScrollIntoView(MyViewModel.SelectedItem);

Unfortunately that causes a nasty visual effect, where current ListView items overlap with the selected item for parts of a second, before everything is rearranged well.

The final solution I found is to call ScrollIntoView() asynchronously via the Dispatcher of the view:

myListView.Loaded += (s, e) => Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
    () => myListView.ScrollIntoView(MyViewModel.SelectedItem));

With this solution the layouting works fine.

like image 197
Matthias Avatar answered Oct 16 '22 00:10

Matthias