滚动到UWP的ListView中的新项目

Sup*_*JMN 3 .net c# xaml uwp windows-community-toolkit

我正在使用包含消息的ListView创建聊天应用程序。发送/接收新消息时,ListView应该滚动到新消息。

我正在使用MVVM,所以ListView看起来像

<ScrollViewer>
    <ItemsControl Source="{Binding Messages}" />
</ScrollViewer>
Run Code Online (Sandbox Code Playgroud)

我该怎么做?

编辑:我试图使此版本在创建行为之前的周年更新之前的版本中。这是我到目前为止的内容:

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

该代码使用UWP Community Toolkit中的 VisualTreeExtensions

但是,调用TransformPoint之后的位置总是返回 {0, 0}

我究竟做错了什么?

DK.*_*DK. 5

从Windows 10版本1607开始,您可以使用ItemsStackPanelItemsUpdatingScrollMode与value KeepLastItemInView,这似乎是最自然的工作。

MS UWP文档(2017-2-8)中有一个`` 反向列表''示例,可以归结为以下XAML:

<ListView Source="{Binding Messages}">
   <ListView.ItemsPanel>
       <ItemsPanelTemplate>
           <ItemsStackPanel
               VerticalAlignment="Bottom"
               ItemsUpdatingScrollMode="KeepLastItemInView"
           />
       </ItemsPanelTemplate>
   </ListView.ItemsPanel>
</ListView>
Run Code Online (Sandbox Code Playgroud)

附带说明一下,是的,我同意您可能要摆脱a,ScrollViewer因为它作为ListView包装是多余的。

更新:

KeepLastItemInView对于“周年纪念版”之前针对Windows 10的应用程序不可用。在这种情况下,确保列表在更改项目集合后始终显示最后一个项目的一种方法是覆盖OnItemsChanged并调用ScrollIntoView。基本实现如下所示:

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());
    }
}
Run Code Online (Sandbox Code Playgroud)