C# WPF:在ListView中添加项时引发事件

C# WPF:在ListView中添加项时引发事件,c#,wpf,events,listview,C#,Wpf,Events,Listview,我正在处理WPF,我正在使用ListView,我需要在向其中添加项目时触发一个事件。我试过这个: var dependencyPropertyDescriptor = DependencyPropertyDescriptor.FromProperty(ItemsControl.ItemsSourceProperty, typeof(ListView)); if (dependencyPropertyDescriptor != null) {

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

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

但它似乎只有在整个集合发生变化时才起作用,我读过这篇文章:,但最好的答案只适用于列表框。我试图将代码更改为ListView,但未能做到这一点

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

注意,这只适用于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
enum允许您的程序通知您任何更改,例如:添加、移动、替换、删除和重置。

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

在我的情况下,我最终来到了一个十字路口,有两个选择

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


(2)每次对listview进行添加、删除或清除调用时,我都会调用另一个模拟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;
    }
}
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));
myListViewControl.Items.Clear();
myListViewControl_CollectionChanged(myListViewControl, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
将项目添加到其他位置的列表视图…

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;
    }
}
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));
myListViewControl.Items.Clear();
myListViewControl_CollectionChanged(myListViewControl, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
清除其他位置的列表视图…

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;
    }
}
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));
myListViewControl.Items.Clear();
myListViewControl_CollectionChanged(myListViewControl, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));

在您发布的问题答案的评论中,您会发现“修改了上面的代码以使其更清晰。这也适用于任何ItemsControl(ListBox或ListView)。”-您有什么特别的问题?@Slugart感谢您的回复,我遇到的问题是,方法
BeginInvoke
不接受声明作为示例。上面说不存在
DispatcherPriority
这对我不起作用。我无法将“ListViewItemCollection”类型的对象强制转换为“System.Collections.Specialized.INotifyCollectionChanged”类型。对于其他好奇的人,
ListView.Items
属于
ItemsCollection
类型。这继承自
CollectionView
,它实现了
INotifyCollectionChanged
。看看MSDN,这对于.NET3.0-4.6是正确的@Arvo
ListViewItemCollection
只实现了
IList、ICollection、IEnumerable
,不从任何东西继承,因此您的异常。也适用于WPF Listbox。如果一个observablecollection被绑定,那么第一次发生的事件将被显示出来!因此,如果同一个值可以多次出现,请使用一个具有一个属性的类来绑定(observablecollection),并相应地设置DisplayMemberPath。Dante的解决方案不适用于您,这很奇怪,尤其是当您的解决方案涉及<代码>InotifyCollection已更改<代码>((INotifyCollectionChanged)MyList.Items)。CollectionChanged+=MyListChanged对我有效。你确定你把括号放对位置了吗?也许它和WPF有关,我不使用它,我使用的是WinForms。不确定,我所知道的只是所有的名称空间都被考虑了,所有的引用都能完美地处理这些对象/类型。我甚至不知道如何将listView.Items的集合强制转换为INotifyCollectionChanged(并不是说无法完成,我只是不明白)。除了那一部分,其他一切看起来都不错。如果你告诉我,我更愿意尝试一下。但就目前情况而言,我的VS2010说不WinForms和WPF是两种完全不同的动物;WinForms
ListView
与WPF
ListView
无关!WPF
ListViewItemCollection
实现了
INotifyCollectionChanged
;这使得WPF强大的数据绑定功能能够检测列表中的更改,并[几乎]自动地使所有内容保持最新。你应该考虑离开WiFrm,尝试WPF——一旦你掌握了它,你就永远不会回头了!谢谢注意。我编辑Dante的答案有几个原因(在顶部为像我这样的纯c#开发者添加了一条注释)。一旦编辑被接受,我就会投我一票。我很快就会试试WPF!;)我也需要从2010年搬到2013年。heheNo问题,除了问题已经标记。。。(不是我的反对票)