如何在向ListView添加数据后滚动到末尾 - WPF

3
我尝试在按钮点击处理程序中添加以下内容:
        ListView listView = MyListView;
        int lastItemIndex = listView.Items.Count - 1;
        listView.ScrollIntoView(listView.Items[lastItemIndex]);
        listView.UpdateLayout();
也与一个命令处理程序相关联,它会向与ListView关联的ObservableCollection添加一个项目。
问题在于,处理程序在我的命令处理程序之前被调用,因此太早了。在处理程序中,ListView还没有看到已添加项目的更新后的ObservableCollection。有什么事件或更好的方法(不改变代码),可以在将我的项目添加到ObservableCollection后使ListView滚动到末尾?我已经找过stackoverflow,但还没有找到答案。谢谢!
2个回答

6

如果您的 ItemSource 是 ObservableCollection,您可以在 Window/UserControl 构造函数中挂钩 CollectionChanged 事件,并且每当集合中添加一个项目时,将其滚动到最后一个项目。

假设您的基础类是 TesClass,下面是如何实现:

((INotifyCollectionChanged)listView.ItemsSource).CollectionChanged +=
     (s, e) =>
     {
         if (e.Action == 
             System.Collections.Specialized.NotifyCollectionChangedAction.Add)
         {
             listView.ScrollIntoView(listView.Items[listView.Items.Count - 1]);
         }
     };

1
太好了,谢谢!如果方便的话,您知道把这个代码块移到模型类附近是否更好?因为 <TestClass> 这个类还是比较领域/模型特定的。有没有什么关于 MVVM 的想法来实现这个呢?再次感谢。 - Buck
使用接口如何?例如 INotifyCollectionChanged(请查看答案中的更新)。这样,您就可以从视图中访问任何模型类进行抽象化。将其移动到ViewModel中似乎不太合适,因为我们在此处执行特定于视图的操作(将滚动项滚动到视图中)。如果有了接口,我想这是完全可以的。只要绑定到实现INotifyCollectionChanged的集合,您就不必担心底层模型类从TestClass更改为任何其他类。(当然) - Rohit Vats

1

试一下这个

VirtualizingStackPanel vsp = (VirtualizingStackPanel)typeof(ItemsControl).InvokeMember("_itemsHost", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic, null, _listView, null);

double scrollHeight = vsp.ScrollOwner.ScrollableHeight;
double offset = scrollHeight * lastItemIndex // itemIndex_ is index of the item which we want to show in the middle of the view

vsp.SetVerticalOffset(offset);

VirtualizingStackPanel虚拟堆栈面板


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接