【问题标题】:UWP Custom ListView to scroll downUWP 自定义 ListView 向下滚动
【发布时间】:2017-08-10 04:23:51
【问题描述】:

所以,我有一个列表视图,我希望在创建项目时滚动到该项目(底部)。因为我使用的是 MVVM,所以我发现了关于如何创建一个从向下滚动的 listview 继承的新控件的很好的解释。问题是this answer (the third) 指的是 6 年前的 WPF。 我正在制作一个 UWP 应用程序,所以我复制了代码并尝试根据我的需要对其进行格式化。下面的代码没有给出任何错误或异常,而是加载了“ChatListView”,因为我完美地调用了它,然后什么也不做。与原始代码相比,cmets 仅稍作修改。

我能做什么?提前谢谢!

public class ChatListView : ListView
{
    //Define the AutoScroll property. If enabled, causes the ListBox to scroll to 
    //the last item whenever a new item is added.
    public static readonly DependencyProperty AutoScrollProperty =
        DependencyProperty.Register(
            "AutoScroll",
            typeof(Boolean),
            typeof(ChatListView),
            new PropertyMetadata(
                true, //Default value.
                new PropertyChangedCallback(AutoScroll_PropertyChanged)));

    //Gets or sets whether or not the list should scroll to the last item 
    //when a new item is added.
    public bool AutoScroll
    {
        get { return (bool)GetValue(AutoScrollProperty); }
        set { SetValue(AutoScrollProperty, value); }
    }

    //Event handler for when the AutoScroll property is changed.
    //This delegates the call to SubscribeToAutoScroll_ItemsCollectionChanged().
    //d = The DependencyObject whose property was changed.</param>
    //e = Change event args.</param>
    private static void AutoScroll_PropertyChanged(
        DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        SubscribeToAutoScroll_ItemsCollectionChanged(
            (ChatListView)d,
            (bool)e.NewValue);
    }

    //Subscribes to the list items' collection changed event if AutoScroll is enabled.
    //Otherwise, it unsubscribes from that event.
    //For this to work, the underlying list must implement INotifyCollectionChanged.
    //
    //(This function was only creative for brevity)

    //listBox = The list box containing the items collection.
    //subscribe = Subscribe to the collection changed event?
    private static void SubscribeToAutoScroll_ItemsCollectionChanged(
        ChatListView listView, bool subscribe)
    {
        INotifyCollectionChanged notifyCollection =
            listView as INotifyCollectionChanged;
        if (notifyCollection != null)
        {
            if (subscribe)
            {
                //AutoScroll is turned on, subscribe to collection changed events.
                notifyCollection.CollectionChanged +=
                    listView.AutoScroll_ItemsCollectionChanged;
            }
            else
            {
                //AutoScroll is turned off, unsubscribe from collection changed events.
                notifyCollection.CollectionChanged -=
                    listView.AutoScroll_ItemsCollectionChanged;
            }
        }
    }

    //Event handler called only when the ItemCollection changes
    //and if AutoScroll is enabled.

    //sender = The ItemCollection.
    //e = Change event args.
    private void AutoScroll_ItemsCollectionChanged(
        object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.Action == NotifyCollectionChangedAction.Add)
        {
            int count = Items.Count;
            ScrollIntoView(Items[count - 1]);
        }
    }

    //Constructor a new ChatListView.
    public ChatListView()
    {
        //Subscribe to the AutoScroll property's items collection 
        //changed handler by default if AutoScroll is enabled by default.
        SubscribeToAutoScroll_ItemsCollectionChanged(
            this, (bool)AutoScrollProperty.GetMetadata(typeof(ChatListView)).DefaultValue);
    }
}

【问题讨论】:

    标签: mvvm uwp custom-controls observablecollection dependency-properties


    【解决方案1】:

    如果您想创建一个聊天应用程序,您可以使用ItemsStackPanel 的ItemsUpdatingScrollMode 特定属性到KeepLastItemInView 值滚动到最新项目。

    用法:

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

    注意:KeepLastItemInView 枚举成员是在 14393 SDK 中引入的。

    相关链接: https://docs.microsoft.com/en-us/uwp/api/Windows.UI.Xaml.Controls.ItemsStackPanel#properties_

    【讨论】:

    • 这比我问的还要多...它不仅会在您在列表中添加内容时向下滚动,而且如果您不在查看最后一项(例如,如果您想要查看以前的消息),它不会向下滚动。完美!!!
    • 正是我需要的!谢谢!
    【解决方案2】:

    接受的答案非常好。但是我有一件事它不会做(至少如果我只是复制并粘贴上面的 XAML):如果在添加新项目时用户离开该页面,它就不会进行预期的滚动,然后他们导航到页面。

    为此,我不得不陷入困境

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
       base.OnNavigatedTo(e);
    
       if (MyListView.Items.Count == 0)
          return;
    
       object lastItem = MyListView.Items[MyListView.Items.Count - 1];
       MyListView.ScrollIntoView(lastItem);
    }
    

    【讨论】:

      猜你喜欢
      • 2021-12-16
      • 2019-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-13
      • 1970-01-01
      • 2014-10-06
      • 1970-01-01
      相关资源
      最近更新 更多