我有UWP / Windows 10应用程序。它包含一个绑定到可观察集合的ListView。列表视图包含反向时间顺序的项目(最新的顶部)。
通常当新物品到达时,我需要将它们插入到集合的顶部。这很好用,插入项目,列表视图通过绑定机制更新新项目。
我的问题是,如果列表视图已滚动到列表顶部,则新项目会动画并按下所有其他项目。由于许多原因,这是有问题的,但是一个大的用户烦恼是他们经常只是点击顶部项目并且它在最后一毫秒时在它们下面发生变化并且他们最终点击了错误的项目。
如果列表已经向下滚动至少顶部项目的高度,则没有问题。该项目插入列表的顶部,滚动条更新以指示您现在可以比以前更进一步向上滚动,但列表的垂直滚动位置不会移动,可见区域/视口保持不变。
当列表中的顶部项目可见并且在其之前插入新项目时,这与我想要的行为相同。垂直滚动位置/视图端口应保持不变,滚动条应更新以指示您现在可以向上滚动,这样做会显示新项目。
有谁知道如何获得此行为?
更新:所以我的问题比我初想的要复杂一些。新项目插入零位置,列表不滚动(如果已向下滚动1个像素或更多)。太棒了。但是,如果随后更新了项目(异步加载额外数据),这会导致项目模板高度发生变化,那么当数据更新时列表会滚动。
例如;
Item1 (top of visible list) Item1 line 2 Item2 Item2 line 2 Then new item added Item0 (not visible) Item0 line 2 Item1 (top of visible list) Item1 line 2 Item2 Item2 line 2 All good. Now item0 updates and it's line 2 becomes a much longer piece of text that wraps; Item0 Item0 AAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAA (List scrolls so everything from here down is now visible) AAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAA Item1 (no longer top of visible list) Item1 line 2 Item2 Item2 line 2
编辑2: 我目前没有物理手机进行测试,但我在Windows 10移动模拟器中尝试过这种情况,那里的行为就是我想要的。即使第一个项目的一小部分滚动屏幕,添加一个新项目,在加载后不久就会增加它的高度,导致视口根本不滚动。然而,我不想要的行为仍然发生在桌面上。这是一个非常令人失望的普遍"应用
答案 0 :(得分:3)
listviews默认ItemsPanel有一个名为 ItemsUpdatingScrollMode 的属性。您可以将其设置为 KeepItemsInView 。
您仍然需要事先向下滚动至少一个像素,使用ListViews内部 ScrollViewer 的 ChangeView 可以实现什么。
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsStackPanel ItemsUpdatingScrollMode="KeepItemsInView" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
答案 1 :(得分:2)
您可以使用ListView函数ScrollIntoView
。一般问题是,此功能仅确保显示Listitem,而不显示项目的位置。(在ListView的顶部/底部)
但你可以用一个小技巧来实现这个目标:
1:记住应该显示的项目
firstitem = ItemListView.Items(0)
2:在此之前插入项目时,请确保Listview的滚动方式是(1 :)中的项目显示在顶部
'Your Insert Function
ItemListView.Items.Insert(0, "test") '<-- Your Insert function
'Scroll in a way that the item from (1:) is shown on top
ItemListView.ScrollIntoView(ItemListView.Items(ItemListView.Items.Count - 1))
ItemListView.UpdateLayout()
ItemListView.ScrollIntoView(firstitem)