【问题标题】:WPF: Raise an Event when Item is added in ListViewWPF:在 ListView 中添加项目时引发事件
【发布时间】:2012-06-08 16:29:26
【问题描述】:

我正在使用 WPF,并且我正在使用 ListView,并且我需要在向其中添加项目时触发一个事件。我试过这个:

var dependencyPropertyDescriptor = DependencyPropertyDescriptor.FromProperty(ItemsControl.ItemsSourceProperty, typeof(ListView));
        if (dependencyPropertyDescriptor != null)
        {
               dependencyPropertyDescriptor.AddValueChanged(this, ItemsSourcePropertyChangedCallback);
        }

.....

 private void ItemsSourcePropertyChangedCallback(object sender, EventArgs e)
    {
         RaiseItemsSourcePropertyChangedEvent();
    }

但它似乎只有在整个集合被更改时才有效,我已经阅读了这篇文章:event-fired-when-item-is-added-to-listview,但最佳答案仅适用于 listBox。我试图将代码更改为 ListView 但我无法做到。

我希望你能帮助我。提前谢谢你。

【问题讨论】:

  • 在您发布的问题的答案中,您会发现“修改了我上面的代码以使其更清晰。这也适用于任何 ItemsControl(ListBox 或 ListView)。” - 你有什么特别的问题?
  • @Slugart 感谢您的回复,我遇到的问题是BeginInvoke 方法不接受声明作为示例。它说DispatcherPriority 不存在

标签: c# wpf events listview


【解决方案1】:

请注意,这只适用于 WPF 列表视图!

经过一些研究,我找到了我的问题的答案,这真的很容易:

public MyControl()
{
    InitializeComponent();
    ((INotifyCollectionChanged)listView.Items).CollectionChanged +=  ListView_CollectionChanged;
}

private void ListView_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)     
{
    if (e.Action == NotifyCollectionChangedAction.Add)
    {
      // scroll the new item into view   
      listView.ScrollIntoView(e.NewItems[0]);
    }
}

实际上,NotifyCollectionChangedAction 枚举允许您的程序通知您任何更改,例如:添加、移动、替换、删除和重置。

【讨论】:

  • 这对我不起作用。我无法将“ListViewItemCollection”类型的对象转换为“System.Collections.Specialized.INotifyCollectionChanged”类型。
  • 对于任何好奇的人,ListView.Items 的类型是 ItemsCollection。这继承自实现INotifyCollectionChangedCollectionView。查看 MSDN,.NET 3.0 - 4.6 确实如此。 @Arvo ListViewItemCollection 仅实现 IList, ICollection, IEnumerable 并且不继承任何东西,因此您的例外。
  • 也适用于 WPF 列表框。如果绑定了 observablecollection,第一次出现的将被带入 View!因此,如果相同的值可以多次出现,请使用具有一个属性的类进行绑定 (observablecollection) 并相应地设置 DisplayMemberPath。
【解决方案2】:

注意:此解决方案适用于 WinForms ListView。

就我而言,我最终走到了岔路口,有两个选择......

(1) 创建一个继承 ListView 类的自定义 ListView 控件。然后添加一个在添加、删除或清除 ListView 时引发的新事件。这条路看起来真的很乱很长。更不用说我需要用新创建的自定义 ListView 控件替换所有原始 ListView 的另一个大问题。所以我放弃了这个!


(2) 对于列表视图的每次添加、删除或清除调用,我还调用了另一个模拟 CollectionChanged 事件的函数。

创建类似函数的新事件...

private void myListViewControl_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    //The projects ListView has been changed
    switch (e.Action)
    {
        case NotifyCollectionChangedAction.Add:
            MessageBox.Show("An Item Has Been Added To The ListView!");
            break;
        case NotifyCollectionChangedAction.Reset:
            MessageBox.Show("The ListView Has Been Cleared!");
            break;
    }
}

将项目添加到其他地方的 ListView...

ListViewItem lvi = new ListViewItem("ListViewItem 1");
lvi.SubItems.Add("My Subitem 1");
myListViewControl.Items.Add(lvi);
myListViewControl_CollectionChanged(myListViewControl, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, lvi, lvi.Index));

清除其他地方的 ListView...

myListViewControl.Items.Clear();
myListViewControl_CollectionChanged(myListViewControl, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));

【讨论】:

  • Dante 的解决方案对您不起作用,这很奇怪,尤其是当您的解决方法涉及...INotifyCollectionChanged((INotifyCollectionChanged)MyList.Items).CollectionChanged += MyListChanged 为我工作。你确定你把括号放在正确的地方吗?
  • 可能跟WPF有关,我没用过,我用的是WinForms。不确定,我所知道的是所有命名空间都被考虑在内,并且所有引用都与这些对象/类型完美配合。我什至不明白如何将 listView.Items 的集合转换为 INotifyCollectionChanged (不是说它不能完成,我只是不明白)。除了那部分,其他一切看起来都不错。如果你告诉我,我更愿意尝试一些事情。但就目前而言,我的 VS 2010 说不! ;)
  • WinForms 和 WPF 是两个完全不同的野兽; WinForms ListView 与 WPF ListView没有任何关系! WPF ListViewItemCollection 实现 INotifyCollectionChanged;这允许 WPF 强大的数据绑定功能检测列表中的更改并[几乎]自动使所有内容保持最新。您应该考虑放弃 WinForms 并尝试 WPF - 一旦掌握了它,您将永远不会回头! :)
  • 谢谢!著名的。我出于几个原因编辑了 Dante 的答案(在顶部为像我这样的纯 c# 开发人员添加了一个注释)。一旦编辑被接受,它就会得到我的投票。我会尽快尝试 WPF! ;) 我也需要从 2010 年搬到 2013 年。呵呵
  • 没问题,除了问题已经标记为wpf...(不是我的反对意见)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-18
  • 1970-01-01
  • 2012-11-17
  • 1970-01-01
  • 2019-03-17
  • 1970-01-01
相关资源
最近更新 更多