2012-06-04 12 views
11

ich auf WPF arbeite und ich bin mit einem Listview, und ich brauche ein Ereignis ausgelöst, wenn ein Element hinzugefügt wird. Ich habe dies versucht:WPF: ein Ereignis auslösen, wenn Artikel in Listview hinzugefügt wird

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

.....

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

aber es scheint nur zu arbeiten, wenn die gesamte Sammlung geändert wird, habe ich diesen Beitrag lesen: event-fired-when-item-is-added-to-listview, aber die beste Antwort gilt nur für eine listBox. Ich habe versucht, den Code in ListView zu ändern, aber ich konnte das nicht tun.

Ich hoffe, dass Sie mir helfen können. Vielen Dank im Voraus. diese

+0

In den Kommentaren der Antwort auf die Frage, die Sie posten, finden Sie "Modified mein Code oben, um es klarer zu machen. Auch das sollte mit einem ItemsControl (ListBox oder ListView) funktionieren. "- Welches Problem hast du speziell? – Slugart

+0

@Slugart Vielen Dank für deine Antwort, das Problem ist, dass die Methode' BeginInvoke' die Deklaration nicht akzeptiert Beispiel. Er sagt, dass 'DispatcherPriority' nicht – Dante

Antwort

37

Hinweis funktioniert nur für einen WPF-Listview!

Nach einigen Recherchen ich die Antwort auf meine Frage gefunden haben, und es ist wirklich einfach:

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

Eigentlich ist die NotifyCollectionChangedAction Enum Ihr Programm ermöglicht es Ihnen, über alle Änderungen zu informieren, wie: Hinzufügen, Verschieben, Ersetzen , Entfernen und Zurücksetzen.

+1

existiert Das ist für mich nicht funktioniert. ich bekomme Konnte nicht das Objekt vom Typ‚ListViewItemCollection‘werfen‚System.Collections.Specialized.INotifyCollectionChanged‘eingeben. –

+1

für alle anderen, die neugierig ist, 'ListView.Items' ist vom Typ 'ItemsCollection'. Dies erbt von 'CollectionView', das' INotifyCollectionChanged' implementiert. Bei MSDN galt dies für .NET 3.0 - 4.6. @Arvo 'ListViewItemCollection' implementiert nur' IList, ICollection, IEnumerable' und erbt von nichts, daher Ihre Ausnahme. –

+0

Funktioniert auch mit WPF Listbox. Wenn eine observablecollection gebunden ist, wird das erste Vorkommen in View gebracht! Wenn derselbe Wert mehrmals vorkommen kann, verwenden Sie eine Klasse mit einer Eigenschaft (observablecollection ) und legen Sie den DisplayMemberPath entsprechend fest. – dba

-1

Hinweis: Diese Lösung wurde für eine WinForms Listview gemeint.

In meinem Fall habe ich am Ende der Wahl zwischen 2 in der Straße zu einer Gabelung kommen ...

(1) Erstellen Sie ein benutzerdefiniertes Listview-Steuerelement, das eine Listview-Klasse erbt. Fügen Sie dann ein neues Ereignis hinzu, das ausgelöst werden soll, wenn ein Element hinzugefügt, gelöscht oder ListView gelöscht wird. Dieser Weg schien wirklich unordentlich und lang zu sein. Ganz zu schweigen von dem anderen großen Problem, das ich alle meine ursprünglichen ListViews mit dem neu erstellten benutzerdefinierten ListView-Steuerelement ersetzen müsste. Also habe ich das weitergegeben!


(2) Mit jedem Hinzufügen, Löschen oder klare Aufforderung zur Listenansicht ich eine andere Funktion auch als das Collection Ereignis zu simulieren.

das neue Ereignis wie Funktion erstellen ...

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

an anderer Stelle zur Listenansicht ein Element hinzufügen ...

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

das Listview anderswo Klar ...

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

Es ist ziemlich merkwürdig, dass Dantes Lösung nicht für Sie funktioniert, besonders wenn Ihr Work-Around ... 'INotifyCollectionChanged' beinhaltet. '((INotifyCollectionChanged) MyList.Items) .CollectionChanged + = MyListChanged' hat für mich funktioniert. Bist du sicher, dass du die Klammern an die richtigen Stellen legst? –

+0

Vielleicht hat es etwas mit WPF zu tun, ich benutze das nicht, ich benutze WinForms. Nicht sicher, alles was ich weiß ist, dass alle Namespaces berücksichtigt werden und alle Referenzen perfekt mit diesen Objekten/Typen funktionieren. Ich verstehe nicht einmal wirklich, wie Sie eine Sammlung von listView.Items zu INotifyCollectionChanged (Nicht zu sagen, dass es nicht möglich ist, ich es einfach nicht bekommen). Alles andere sieht gut aus außer diesem Teil. Ich bin mehr als bereit, etwas auszuprobieren, wenn du es mir erzählst. Aber so wie es aussieht, sagt mein VS 2010 nein! ;) –

+2

WinForms und WPF sind zwei völlig verschiedene Biester; Ein WinForms 'ListView' hat ** nichts ** mit einem WPF' ListView' zu tun! Die WPF 'ListViewItemCollection' implementiert' INotifyCollectionChanged'; Dadurch können WPFs leistungsstarke Datenbindungsfunktionen Änderungen in der Liste erkennen und [fast] * automatisch * alles auf dem neuesten Stand halten. Sie sollten erwägen, WinForms zurückzulassen und WPF auszuprobieren - sobald Sie den Dreh raus haben, werden Sie nie mehr zurückschauen! :) –

Verwandte Themen