2012-06-04 87 views
11

我正在使用WPF,我使用的是ListView,并且需要在将项目添加到项目时触发事件。我曾经尝试这样做: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,但最佳答案只适用于列表框。我试图将代码更改为ListView,但我无法做到这一点。

我希望你能帮助我。先谢谢你。

+0

在回复您发布的问题的评论中,您会发现“修改了上面的代码,使其更加清晰。此外,这应该与任何ItemsControl(ListBox或ListView)。“ - 你有什么问题特别是? – Slugart

+0

@Slugart谢谢你的回复,我遇到的问题是,方法'BeginInvoke'不接受声明作为例如,它说'DispatcherPriority'不存在 – Dante

回答

37

注意这只适用于WPF ListView!

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

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枚举允许你的程序告知您的任何改变,例如:添加,移动,替换,删除并重置。

+1

这对我无效我无法投射'ListViewItemCollection'类型的对象来键入'System.Collections.Specialized.INotifyCollectionChanged' –

+1

对于任何其他好奇的人, 'ListView控件。Items'属于'ItemsCollection'类型。这从实现了'INotifyCollectionChanged'的'CollectionView'继承。看看MSDN,这对于.NET 3.0-4.6来说是正确的。 @Arvo'ListViewItemCollection'只实现'IList,ICollection,IEnumerable'并且不从任何东西继承,因此你是个例外。 –

+0

也适用于WPF列表框。如果可观察集合被绑定,则第一个事件将被带入View!因此,如果多次出现相同的值,请使用具有一个属性的类进行绑定(observablecollection ),并相应地设置DisplayMemberPath。 – dba

-1

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

在我来说,我结束了即将在2只选择一个岔路口...

(1)创建继承的ListView的类的自定义ListView控件。然后添加一个新事件,当任何项目添加,删除或清除ListView时引发。这条路似乎非常混乱和漫长。更不用说我需要用新创建的Custom 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)); 
+0

但丁的解决方案不适合你,尤其是当你的解决方法涉及到...... INotifyCollectionChanged。 '((INotifyCollectionChanged)MyList.Items).CollectionChanged + = MyListChanged'为我工作。你确定把括号放在正确的地方吗? –

+0

也许它与WPF有关,我不使用它,我使用WinForms。不知道,我所知道的是所有的名称空间都被考虑到了,所有的引用对这些对象/类型都是完美的。我甚至没有真正知道如何将一个listView.Items集合转换为INotifyCollectionChanged(并不是说它不能完成,我只是不明白它)。除此之外,其他一切看起来都不错。如果你告诉我,我更愿意尝试一些东西。但就我个人而言,VS 2010说不! ;) –

+2

WinForms和WPF是两个完全不同的野兽;一个WinForms的'ListView'有**没有任何**与WPF'ListView'做! WPF的'ListViewItemCollection'实现'INotifyCollectionChanged';这允许WPF的强大的数据绑定功能来检测列表中的变化,并且[几乎] *自动地*保持一切都是最新的。你应该考虑离开WinForms并试用WPF--一旦你掌握了它,你就永远不会回头看! :) –