2014-01-25 40 views
1

我尝试添加一个按钮单击处理如下:如何滚动到结束的ListView新增的数据后 - WPF

 ListView listView = MyListView; 
     int lastItemIndex = listView.Items.Count - 1; 
     listView.ScrollIntoView(listView.Items[lastItemIndex]); 
     listView.UpdateLayout(); 

按一下按钮也与添加项目到的ObservableCollection命令处理程序相关联与ListView相关联。

问题是在我的命令处理程序之前调用了按钮单击处理程序,因此为时尚早。在按钮点击处理程序中,ListView还没有看到更新的ObservableCollection和添加的项目。什么事件或更好,我可以做什么,而无需更改后面的代码让我的项目添加到ObservableCollection后ListView滚动到最后?我看过,但没有在stackoverflow答案。谢谢!

回答

2

如果的ItemSource是的ObservableCollection,你可以连接到CollectionChanged事件在窗口/用户控件的构造和滚动最后一个项目进入视野,只要项目获得加入收藏

假设你的底层类是TesClass,这是你会怎么做:

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

大和感谢!如果方便的话,你知道是否更好地将它靠近模型类?想知道自是相当域/模型特定。关于如何用MVVM来做到这一点的想法?再次感谢。 – Buck

+0

如何使用接口,而不是'INotifyCollectionChanged'(检查答案更新)?通过这种方式,您可以抽象出从视图中访问任何模型类。将它移动到ViewModel似乎也不正确,因为我们在这里查看特定的东西(将项目滚动到视图中)。有了接口,我认为它非常好。如果底层模型类从TestClass更改为任何其他类,则不必担心。 (当然只要你绑定到实现INotifyCollectionChanged的集合)。 –

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