2012-06-04 121 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--一旦你掌握了它,你就永遠不會回頭看! :) –