【问题标题】:Show latest item added to an ItemsControl显示添加到 ItemsControl 的最新项目
【发布时间】:2011-05-05 22:01:24
【问题描述】:

我无法相信在搜索了 google 和 SO 半小时后我找不到解决方案。

我的 ViewModel 中有一个 ObservableCollection<string>,我的 View 中的 ListBox 绑定到:

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

当一个按钮被点击时,一个新线程会做一些事情,并且使用 Observable,VM 监控从该异步操作返回的字符串并将这些字符串添加到它的 Output ObservableCollection。添加字符串没有问题,但是如何让视图始终显示最新项目(最近添加的项目)?

【问题讨论】:

    标签: wpf itemscontrol


    【解决方案1】:

    您的项目是否显示在列表中但更靠后?如果是这种情况,您需要做的就是告诉列表将该项目滚动到视图中。您可以通过订阅 ListBox.Items 属性的 ColllectionChanged 来做到这一点。要做到这一点有点棘手,因为您必须强制转换它,但您可以使用这样的代码来做到这一点:

    ((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);
            }
        }
    

    另外,我刚刚找到了一种方法,您可以使用非常酷的附加属性来做到这一点。在这里查看: http://michlg.wordpress.com/2010/01/16/listbox-automatically-scroll-currentitem-into-view/

    【讨论】:

    • 没有骰子 - newListItem 始终为空。并且您第一次发布的代码不起作用,可能是因为它在 ListBox 集合中存在该项目之前被触发。不过还是谢谢。
    • 如果将newListItem直接设置为e.NewItems[0],它确实有效。但是,如果相邻插槽中有重复的项目(例如,相同的文本重复 x 次),则只会滚动到第一个。更改您的代码,我会选择您的答案。
    • 完成 - 请注意附加属性方法的链接。
    • 附加属性是一个好主意,但它专注于 ListBox 的 CurrentItem - 过去,我在使用该属性滚动到时遇到问题(它并不总是 CurrentItem 是设置为 ListBox 集合中的最新项目)。您的代码运行良好。
    • 所有(可能通常是多余的)调度程序使用是什么? (在我看来,SystemIdle 的操作也不像)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-09
    • 1970-01-01
    • 1970-01-01
    • 2015-02-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多