diff --git a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_ListViewBase.cs b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_ListViewBase.cs index 45edf67e6dee2ff1cfaefcd17e0dff36defd568d..da6e41c825fd773339d89963563b9ee62e4f2fb8 100644 --- a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_ListViewBase.cs +++ b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_ListViewBase.cs @@ -919,6 +919,67 @@ namespace Uno.UI.RuntimeTests.Tests.Windows_UI_Xaml_Controls Assert.AreEqual(4, materialized); } + + [TestMethod] + [RunsOnUIThread] +#if __IOS__ || __ANDROID__ + [Ignore("Disabled because of animated scrolling, even when explicitly requested.")] +#endif + public async Task When_Large_List_Scroll_To_End_Then_Back_Up_And_First_Item() + { + var materialized = 0; + var container = new Grid { Height = 500, Width = 100 }; + + var list = new ListView + { + ItemContainerStyle = NoSpaceContainerStyle, + ItemTemplate = new DataTemplate(() => + { + var tb = new TextBlock(); + tb.SetBinding(TextBlock.TextProperty, new Binding()); + var border = new Border() + { + Height = 50, + Child = tb + }; + + materialized++; + + return border; + }) + }; + container.Children.Add(list); + + var source = new ObservableCollection(Enumerable.Range(0, 50)); + list.ItemsSource = source; + + WindowHelper.WindowContent = container; + await WindowHelper.WaitForIdle(); + + for (int i = 0; i < 3; i++) + { + ScrollTo(list, 1000000); // Scroll to end + + await Task.Delay(200); + await WindowHelper.WaitForIdle(); + + ScrollTo(list, 5); // Scroll to end + + await Task.Delay(200); + await WindowHelper.WaitForIdle(); + + var firstContainer = (FrameworkElement)list.ContainerFromIndex(0); + + firstContainer.Should().NotBeNull(); + LayoutInformation.GetLayoutSlot(firstContainer).Y.Should().BeLessOrEqualTo(0); + + var secondContainer = (FrameworkElement)list.ContainerFromIndex(1); + + secondContainer.Should().NotBeNull(); + LayoutInformation.GetLayoutSlot(secondContainer).Y.Should().Be(50); + } + } + [TestMethod] [RunsOnUIThread] #if __IOS__ || __ANDROID__ diff --git a/src/Uno.UI/UI/Xaml/Controls/ListViewBase/VirtualizingPanelLayout.managed.cs b/src/Uno.UI/UI/Xaml/Controls/ListViewBase/VirtualizingPanelLayout.managed.cs index e3ec40948ea07dadb618555e1cafad48cd8901ab..0f8bbbcd214b9f77086d3cc6e529a05d545fd3cd 100644 --- a/src/Uno.UI/UI/Xaml/Controls/ListViewBase/VirtualizingPanelLayout.managed.cs +++ b/src/Uno.UI/UI/Xaml/Controls/ListViewBase/VirtualizingPanelLayout.managed.cs @@ -266,7 +266,7 @@ namespace Windows.UI.Xaml.Controls // the line based on the average line height. var index = (int)(ScrollOffset / _averageLineHeight); _dynamicSeedStart = ScrollOffset - _averageLineHeight; - _dynamicSeedIndex = Uno.UI.IndexPath.FromRowSection(index - sign, 0); + _dynamicSeedIndex = Uno.UI.IndexPath.FromRowSection(index == 0 ? -1 : index - sign, 0); } while (unappliedDelta > 0)