滚动到UWP的ListView中的新项目 [英] Scroll to new item in ListView for UWP
问题描述
我正在使用包含消息的ListView创建聊天应用程序.发送/接收新邮件时,ListView应滚动到新邮件.
I'm creating a chat application with a ListView that contains the messages. When a new message is sent/received, the ListView should scroll to the new message.
我正在使用MVVM,所以ListView看起来像
I'm using MVVM, so the ListView looks like
<ScrollViewer>
<ItemsControl Source="{Binding Messages}" />
</ScrollViewer>
我该怎么办?
我试图在创建行为"的周年更新"之前的版本中进行此操作.这是我到目前为止的内容:
I tried to make this work in versions prior to the Anniversary Update creating a Behavior. This is what I have so far:
public class FocusLastBehavior : Behavior<ItemsControl>
{
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.Items.VectorChanged += ItemsOnVectorChanged;
}
private void ItemsOnVectorChanged(IObservableVector<object> sender, IVectorChangedEventArgs @event)
{
var scroll = VisualTreeExtensions.FindVisualAscendant<ScrollViewer>(AssociatedObject);
if (scroll == null)
{
return;
}
var last = AssociatedObject.Items.LastOrDefault();
if (last == null)
{
return;
}
var container = AssociatedObject.ContainerFromItem(last);
ScrollToElement(scroll, (UIElement)container);
}
private static void ScrollToElement(ScrollViewer scrollViewer, UIElement element,
bool isVerticalScrolling = true, bool smoothScrolling = true, float? zoomFactor = null)
{
var transform = element.TransformToVisual((UIElement)scrollViewer.Content);
var position = transform.TransformPoint(new Point(0, 0));
if (isVerticalScrolling)
{
scrollViewer.ChangeView(null, position.Y, zoomFactor, !smoothScrolling);
}
else
{
scrollViewer.ChangeView(position.X, null, zoomFactor, !smoothScrolling);
}
}
}
代码使用了 UWP社区工具包
但是,调用TransformPoint之后的位置始终返回{0, 0}
However, the position after the call to TransformPoint always returns {0, 0}
我在做什么错了?
推荐答案
从Windows 10版本1607开始,您可以使用 ItemsUpdatingScrollMode
,其值为KeepLastItemInView
,这似乎最适合该工作.
As of Windows 10, version 1607 you can use ItemsStackPanel
.ItemsUpdatingScrollMode
with the value KeepLastItemInView
, which seems like the most natural fit for the job.
有一个反向列表" MS UWP文档(2017-2-8)中的示例将归结为以下XAML:
There is an "Inverted Lists" example in MS UWP docs (2017-2-8) that would boil down to this XAML:
<ListView Source="{Binding Messages}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsStackPanel
VerticalAlignment="Bottom"
ItemsUpdatingScrollMode="KeepLastItemInView"
/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
顺便说一句,是的,我同意您可能想要摆脱ScrollViewer
的想法,因为它作为ListView
包装器是多余的.
On a side note, yes, I'd agree that you may want to get rid of a ScrollViewer
as it's redundant as a ListView
wrapper.
更新:
KeepLastItemInView
不适用于周年纪念版"之前针对Windows 10的应用程序.如果是这种情况,确保更改项目集合后列表始终显示最后一个项目的一种方法是覆盖 ScrollIntoView
.基本实现如下所示:
KeepLastItemInView
is not available for applications that target Windows 10 prior to the "Anniversary Edition". If that's the case, one way to make sure that a list always displays the last item after item collection is changed is to override OnItemsChanged
and call ScrollIntoView
. A basic implementation would look like this:
using System.Linq;
using Windows.UI.Xaml.Controls;
public class ChatListView : ListView
{
protected override void OnItemsChanged(object e)
{
base.OnItemsChanged(e);
if(Items.Count > 0) ScrollIntoView(Items.Last());
}
}
这篇关于滚动到UWP的ListView中的新项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!