- 
                Notifications
    
You must be signed in to change notification settings  - Fork 1.9k
 
ListView.ScrollTo doesn't animate on UWP #2048
Description
Bug report best practices: https://github.com/xamarin/Xamarin.Forms/wiki/Submitting-Issues
ListView.ScrollTo does not animate the scrolling on UWP when animated is set to True. This works correctly on Android.
Steps to Reproduce
- Create a Xamarin Forms App (shared project including UWP and Android)
 - On the main page, put a ListView that binds to a viewmodel that has an Observable Collection of Strings. The ItemTemplate of the List View contains a Label that binds to the string and a button.
 
<ListView x:Name="lstItems" ItemsSource="{Binding Items}" RowHeight="48" HeightRequest="144" Margin="0,0,24,24" VerticalOptions="Start"  HasUnevenRows="False" >
            
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Grid Margin="8,8,24,8">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="3*"/>
                                <ColumnDefinition Width="1*"/>
                            </Grid.ColumnDefinitions>
                            <Label Text="{Binding}"/>
                            <Button x:Name="btnNext" Text="Next"  Grid.Column="1" Clicked="btnNext_Clicked"/>
                        </Grid>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
           </ListView>
- In the btnNext_Clicked event in the code behind, use the ListView Scrollto method to scroll the next item to the top of the screen with animation set to true
 
private void btnNext_Clicked(object sender, EventArgs e)
        {
            MainPageViewModel vm = this.BindingContext as MainPageViewModel;
            Button myButton = sender as Button;
            Item myItem = myButton.BindingContext as Item;
            int Index;
            Index = vm.Items.IndexOf(myItem);
           
            if (Index < vm.Items.Count - 1)
            {
                lstItems.ScrollTo(vm.Items[Index + 1], ScrollToPosition.Start, true);
            }
        }
Expected Behavior
The next item in the list will visibly move to the top of the screen
Actual Behavior
The next item suddenly appears at the top of the screen
Basic Information
I believe this happens on UWP because the Xamarin Form's ListView.ScrollTo method is implemented using the UWP native methodl ScrollIntoView (  List.ScrollIntoView(c, ScrollIntoViewAlignment.Leading); )
and ScrollIntoView does not animate the scrolling. To get animation to happen, you would instead use the ChangeView method of the ScrollViewer part of the UWP ListView.  For Example:
ScrollViewer theScrollViewer = GetVisualChild<ScrollViewer>(lstItems);
 double yPos = IndexToScrollTo * ItemHeight; //only works when item height is constant
 double scrollOffset = yPos - theScrollViewer.VerticalOffset;
 
await Task.Delay(1);
 theScrollViewer.ChangeView(null, theScrollViewer.VerticalOffset + scrollOffset, null, false);
I tested the above technique using a custom renderer for the Listview on UWP and it worked (the item animated as expected).
Here is the definition for the UWP ChangeView method:
public bool ChangeView(Nullable<Double> horizontalOffset, Nullable<Double> verticalOffset, Nullable<Single> zoomFactor, Boolean disableAnimation) 
- Version with issue: 2.5.0.280555
 - Last known good version:
 - IDE: Visual Studio 2017
 - Platform Target Frameworks: 
- UWP: 10.0.16299 Fall Creator's Update
 
 - Nuget Packages:
Xamarin Forms 2.5.0.280555
Net Standard Library 2.0.1 - Affected Devices:
Desktop, Tablet