Wpf 显示添加到ItemsControl的最新项目

Wpf 显示添加到ItemsControl的最新项目,wpf,itemscontrol,Wpf,Itemscontrol,我不敢相信,在搜索了谷歌半个小时后,我竟然找不到解决这个问题的办法 我的视图模型中有一个可观察集合,视图中的列表框绑定到: <ListBox ItemsSource="{Binding Output}" IsSynchronizedWithCurrentItem="True" /> 单击按钮时,一个新线程会执行一些操作,VM会使用一个Observable监视从异步操作返回的字符串,并将字符串添加到其输出ObservableCollection。添加字符串没有问题,但是如何使视图

我不敢相信,在搜索了谷歌半个小时后,我竟然找不到解决这个问题的办法

我的视图模型中有一个
可观察集合
,视图中的
列表框
绑定到:

<ListBox ItemsSource="{Binding Output}" IsSynchronizedWithCurrentItem="True" />


单击按钮时,一个新线程会执行一些操作,VM会使用一个Observable监视从异步操作返回的字符串,并将字符串添加到其
输出
ObservableCollection
。添加字符串没有问题,但是如何使视图始终显示最新的项目(最近添加的项目)?

您的项目是否显示在列表中,但仅显示在较低的位置?如果是这种情况,您只需告诉列表将该项目滚动到视图中即可。您可以通过订阅ListBox.Items属性的CollectionChanged来实现这一点。要做到这一点有点棘手,因为您必须强制转换它,但您可以使用如下代码:

((INotifyCollectionChanged)MainListBox.Items).CollectionChanged +=  ListBox_CollectionChanged;
private void ListBox_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.NewItems.Count > 0)
        {
            Dispatcher.BeginInvoke(() =>
            {
                 MainListBox.ScrollIntoView(e.NewItems[0]);
            }, DispatcherPriority.SystemIdle);
        }
    }
然后在该事件中可以添加如下代码:

((INotifyCollectionChanged)MainListBox.Items).CollectionChanged +=  ListBox_CollectionChanged;
private void ListBox_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.NewItems.Count > 0)
        {
            Dispatcher.BeginInvoke(() =>
            {
                 MainListBox.ScrollIntoView(e.NewItems[0]);
            }, DispatcherPriority.SystemIdle);
        }
    }
另外,我刚刚找到了一种方法,你可以做一个附加属性,这是非常酷。在这里查看:

无骰子-
newListItem
始终为空。您第一次发布的代码不起作用,可能是因为它是在ListBox集合中存在该项之前触发的。谢谢。如果您直接将
newListItem
设置为
e.NewItems[0]
,它实际上可以工作。但是,如果相邻插槽中有重复的项目(例如,相同的文本重复x次),则只有第一个项目将滚动到。更改您的代码,我将选择您的答案。完成-请注意附加属性方法的链接。附加属性是一个不错的主意,但它集中在列表框的CurrentItem上-过去,我在使用该属性滚动到时遇到问题(似乎并不总是将CurrentItem设置为ListBox集合中的最新项)。您的代码工作正常。所有(可能经常是冗余的)Dispatcher使用是怎么回事?(在我看来也不像是针对
SystemIdle
的操作)