Xaml UWP ListView在索引0处插入项时防止滚动

Xaml UWP ListView在索引0处插入项时防止滚动,xaml,listview,scroll,win-universal-app,uwp,Xaml,Listview,Scroll,Win Universal App,Uwp,我有UWP/Windows10应用程序。它包含绑定到可观察集合的ListView。列表视图包含的项目按相反的时间顺序排列(最新的在顶部) 通常,当新物品到达时,我需要将它们插入收藏的顶部。这可以正常工作,通过绑定机制插入项目,并使用新项目更新列表视图 我的问题是,如果列表视图已经滚动到列表的顶部,则新项目将进入动画并向下推所有其他项目。这是有问题的,原因有很多,但一个大的用户烦恼是,他们经常刚要点击顶部的项目,它在最后毫秒的时候在他们下面发生了变化,最后他们点击了错误的项目 如果列表至少向下滚动

我有UWP/Windows10应用程序。它包含绑定到可观察集合的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 项目1(可见列表的顶部) 项目1第2行 项目2 项目2第2行 然后添加新项目 项目0(不可见) 项目0第2行 项目1(可见列表的顶部) 项目1第2行 项目2 项目2第2行 一切都好。现在item0更新了,它的第2行变成了一段更长的文本,可以换行; 项目0 第0项aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Item1(不再位于可见列表的顶部) 项目1第2行 项目2 项目2第2行 编辑2:
我目前还没有一部物理手机可以测试,但我刚刚在Windows10移动模拟器中尝试过,那里的行为正是我想要的。即使第一个项目的一小部分从屏幕上滚动,在加载后不久添加一个增加其高度的新项目也不会导致查看端口滚动。然而,我不希望的行为仍然发生在桌面上。这对于一个“通用”应用程序来说是非常令人失望的。

您可以使用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)
“插入函数”

ItemListView.Items.Insert(0,“测试”)”ListView默认ItemsPanel有一个名为ItemsUpdatingScrollMode的属性。您可以将其设置为KeepItemsInView

<ListView.ItemsPanel>
  <ItemsPanelTemplate>
    <ItemsStackPanel ItemsUpdatingScrollMode="KeepItemsInView" />
  </ItemsPanelTemplate>
</ListView.ItemsPanel>
您仍然需要提前向下滚动至少一个像素,使用ListViews internalScrollViewerChangeView可以实现这一点

<ListView.ItemsPanel>
  <ItemsPanelTemplate>
    <ItemsStackPanel ItemsUpdatingScrollMode="KeepItemsInView" />
  </ItemsPanelTemplate>
</ListView.ItemsPanel>


谢谢。我应该提到,我已经尝试过了,但它经常(并非总是)在列表滚动时导致弹出和显示问题。我正在寻找一种从一开始就阻止滚动的方法,而不是在事后试图撤销它。顺便说一句,我相信如果你想使用这个解决方案,你可以跳过第一个ScrollIntoView调用。保留updatelayout(),然后使用带有两个参数并指定“leadingedge”的重载进行一次滚动查看调用;ScrollingToView(firstitem,ScrollingToViewAlignment.Leading)第二个参数表示滚动,因此项目的上边缘与列表框的上边缘是内联的,滚动刚好足以使“firstitem”保持在顶部。这会减少(但不会使elimiante闪烁)并且不会导致列表末尾的项目被实现。那么这就是解决方案吗?因为在我的例子中,我使用VisualTreeHelper获取scrollviewer,获取TransformToVisual矩阵,然后是ChangeView,问题是您需要捕获实例化的控件。谢谢,这正是我想要的,事实上这是默认行为(我在运行时选中了使用中的items面板,并且该属性已按此方式设置)。不幸的是,虽然它适用于简单案例,但不适用于我的实际场景。请参阅我编辑的问题,了解问题的后半部分。我们会发现,您可能在listview中发现错误,或者您的案例不在默认实现中。您可以创建自己的面板,自己进行计算,或者(可能更好)添加后不要更改列表项的大小。(YouTube在加载后更改列表,并且在那里也很糟糕…)我将接受这一点,因为它从技术上回答了第一次提出的问题,尽管它并不能解决我的实际问题。不改变列表项的大小并不是一个真正的选项-我希望列表中的数据,但我不能(也不应该)同步检索。鉴于W10 mobile上的行为是我想要的,并且与桌面版本不同,我认为这是一个bug…但是bug是在桌面版本还是移动版本,以及它是否会被修复是完全不同的问题。