2012-06-04 29 views
11

'da eklendiğinde bir Olay Yükseltme WPF üzerinde çalışıyorum ve bir ListView kullanıyorum ve bir öğe eklendiğinde bir olayı tetiklemem gerekiyor. Bunu denedim: event-fired-when-item-is-added-to-listview, ama en iyi cevabı:WPF: Öğe, ListView

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

.....

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

Ama Bu tüm koleksiyonu değiştirildiğinde yalnızca çalışıyor görünüyor, bu yayını okudum sadece bir listeBox için geçerlidir. Kodu ListView olarak değiştirmeye çalıştım ama bunu yapamadım.

Umarım bana yardımcı olabilirsiniz. Şimdiden teşekkür ederim.

+0

Gönderdiğiniz soruya verilen cevapların yorumlarında, daha net olması için yukarıdaki kodu değiştirdim. Ayrıca bu, herhangi bir ItemsControl (ListBox veya ListView) ile çalışmalıdır. "- Hangi sorunla karşılaşıyorsunuz? – Slugart

+0

@Slugart Cevabınız için teşekkür ederiz, sorun şu ki" BeginInvoke "yöntemi bildirimi kabul etmiyor. Örnek: "DispatcherPriority" mevcut değil – Dante

cevap

37

Not Bu yalnızca bir WPF Liste Görünümü için çalışır!

bazı araştırmadan sonra Sorumun cevabını bulduk ve Gerçekten çok kolaydır: Aslında

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 programınızın gibi herhangi bir değişiklik konusunda bilgilendirmek sağlar:, Taşı ekleyin Değiştir , Kaldır ve Sıfırla.

+1

Bu benim için işe yaramıyor. 'System.Collections.Specialized.INotifyCollectionChanged' yazmak için 'ListViewItemCollection' türünde nesne için açılamıyor. –

+1

Meraklı herkes için 'liste görünümü.Öğeler, 'ItemsCollection' türündendir. Bu, "INotifyCollectionChanged" öğesini uygulayan CollectionView' öğesinden devralınır. MSDN'ye baktığımızda, bu .NET 3.0 - 4.6 için geçerliydi. @Arvo 'ListViewItemCollection' sadece IList, ICollection, IEnumerable'ı uygular ve hiçbir şeyden miras almaz, dolayısıyla istisnasız. –

+0

WPF Listbox ile de çalışır. Gözlemlenebilir bir bağlanmışsa, ilk olay Görünüm! Bu nedenle, aynı değer birden çok kez ortaya çıkabilirse, bir özellik ile bir özelliği (gözlemlenebilirkolllection ) kullanın ve DisplayMemberPath'ı buna göre ayarlayın. – dba

-1

Not: Bu çözüm bir WinForms ListView için kullanıldı. Benim durumumda ben 2 seçenekleri ile yol ayrımında geliyor sona erdi yılında

...

(1) bir ListView sınıfı devralan bir özel liste görünümü denetimi oluşturun. Daha sonra, herhangi bir öğe eklendiğinde, silinirken veya ListView temizlendiğinde yükseltilecek yeni bir etkinlik ekleyin. Bu yol gerçekten dağınık ve uzun görünüyordu. Yeni oluşturulan Özel ListView denetimi ile tüm orijinal ListView'leri değiştirmem gerekecek diğer büyük sorundan bahsetmiyorum. Ben de bundan geçtim!


(2) Her ile silme, ekleme, yoksa da CollectionChanged olayı simüle başka bir fonksiyon denir liste görünümü için açık çağrı.

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

başka yerde ListView bir öğe ekleme

fonksiyonu gibi yeni bir etkinlik oluşturmak

... ... ListView başka yerde

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

Temizle ...

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

Dante'nin çözümünün sizin için işe yaramadığı oldukça garip, özellikle de işiniz sırasında ... 'INotifyCollectionChanged' içeriyorsa. '((INotifyCollectionChanged) MyList.Items) .CollectionChanged + = MyListChanged' benim için çalıştı. Parantezini doğru yerlere koyduğunuzdan emin misiniz? –

+0

Belki WPF ile bir ilgisi var, bunu kullanmıyorum, WinForms kullanıyorum. Emin değilim, tek bildiğim, tüm ad alanlarının açıklanması ve tüm referansların bu nesneler/türlerle mükemmel çalışmasıdır. Ben gerçekten bir liste listView.Items koleksiyonunu nasıl yapabilirim? INotifyCollectionChanged (Bu yapamayacağını söyleme, sadece anlamıyorum). Her şey o kısım dışında iyi görünüyor. Bana anlatırsan daha sonra bir şeyler denemeye razıyım. Ama VS 2010'da olduğu gibi hayır diyor! ;) –

+2

WinForms ve WPF iki tamamen farklı yaratıktır; Bir WinForms 'ListView' bir WPF' ListView' ile yapmak için ** bir şey ** var! WPF ListViewItemCollection 'INotifyCollectionChanged'i uygular; Bu, WPF'nin güçlü veri bağlama özelliklerinin listedeki değişiklikleri algılamasına ve [neredeyse] * otomatik olarak * herşeyi güncel tutmasına izin verir. WinForms'u geride bırakıp WPF'yi denemeyi düşünmelisiniz - bir kere asarsanız, asla geri bakmayacaksınız! :) –

İlgili konular