2016-08-12 8 views
0

ich eine beobachtbare Sammlung haben, aber nach dem collecion aktualisieren, meine Listview ist die Aktualisierung nicht einmal nach Property Changed-Ereignis ein code Anheben: -INotifyPropertyChanged funktioniert nicht MVVM

Schauen Sie unter XAML: -

<ListView Grid.Row="1" Grid.Column="0" Name="lvGroups" Margin="0,34,0,0" 
Grid.RowSpan="2" ItemsSource="{Binding Path=*VideoGroupList*,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"> 
<GridView> 
<GridViewColumn Width="150" DisplayMemberBinding="{Binding *Name*}" /> 
</GridView> 

Schauen Sie unten Klasse

public class VideoGroupViewModel : ObservableEnitiy 
{ 
    public ObservableCollection<Group> VideoGroupList { get; set; } 
} 

    public abstract class ObservableEnitiy : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 
    protected virtual void OnPropertyChanged(string propertyName) 
    { 
    this.VerifyPropertyName(propertyName); 
     if (this.PropertyChanged != null) 
     { 
      var e = new PropertyChangedEventArgs(propertyName); 
      this.PropertyChanged(this, e); 
     } 
    } 
} 

[Serializable] 
public class Group : PropertyChangedNotification 
{ 
    public int ID { get; set; } 
    [Required(ErrorMessage = "Group name is required.")] 
    public string *Name* 
    { 
     get { return GetValue(() => Name); ; } 
     set 
     { 
      SetValue(() => Name, value); 
     } 
    } 
    [XmlIgnore] 
    public bool IsSelected { get; set; } 
} 


    protected T GetValue<T>(Expression<Func<T>> propertySelector) 
    { 
     string propertyName = GetPropertyName(propertySelector); 

     return GetValue<T>(propertyName); 
    } 

Ich rufe diese Weise

VideoGroupList = new ObservableCollection<Group>(videoGroupManager.GetVideoGroups()); 
OnPropertyChanged("VideoGroupList"); 
+0

In der Regel wird dieses Problem durch das Steuerelement Refreshereignis verursacht, das nicht erkennt, dass sich das Steuerelement geändert hat. Der Trick, der normalerweise funktioniert, ist das Hinzufügen von VideoGroupList = null vor dem Aktualisieren der Liste. – jdweng

+0

Als Anmerkung ist die Einstellung 'Mode = TwoWay' und' UpdateSourceTrigger = PropertyChanged' für die ItemsSource-Bindung redundant. Dies hat keine Auswirkungen, da kein Datenfluss vom Ziel zur Quelleigenschaft der Bindung erfolgt. – Clemens

+0

@jdweng ich versuchte mit VideoGroupList = null vor dem Aktualisieren der Liste, aber nicht funktioniert. :( – user3631797

Antwort

1

Fügen Sie die folgenden using-Anweisungen:

using System.Collections.Generic; 
using System.Linq; 

Ihre VideoGroupList Linie ändern:

VideoGroupList.Clear(); 
    videoGroupManager.GetViewGroups().ToList().ForEach(x => VideoGroupList.Add(x)); 

Diese bessere Benachrichtigung der Änderung in die ObservableCollection gebaut nutzt

+0

Foreach funktioniert hier nicht – user3631797

+0

Sorry, ich habe die Antwort bearbeitet – benPearce

+0

Es hat leider nicht funktioniert – user3631797

0

Nach dem MSDN-Dokument wird CollectionChanged beim Hinzufügen, Entfernen und Ändern eines Elements in einer ObservableCollection ausgelöst. Ich fand jedoch, dass dies nicht der Fall ist. ObservableCollection.CollectionChanged wird nur auf add/remove geworfen. Ich verwende stattdessen this FullyObservableCollection here, mit der Änderung, T meine ViewModelBase-Klasse anstelle von INotifyPropertyChanged direkt zu haben.

Wenn ich mein Eigentum erklären dann, verwende ich einen Ausschnitt mit der folgenden Ausgabe: private FullyObservableCollection<Group> _videoGroupList; public FullyObservableCollection<Group> VideoGroupList { get { return _videoGroupList; } set { if(_videoGroupList == value) return; var nil = _videoGroupList == null; _videoGroupList = value; // If null before and not after (declaring it after being null), // call OnPropertyChanged on Change of Collection. if(nil && _videoGroupList != null) _videoGroupList.CollectionChanged += (s,e) => OnPropertyChanged(nameof(VideoGroupList)); OnPropertyChanged(); } } Auf diese Weise werden Sie immer haben INotifyPropertyChanged Benachrichtigungen auf Hinzufügen, Entfernen, Ersetzen und Aktion Ändern Sie auf den Sammlungen und jedem einzelnen seiner Mitglieder . Es wird Ihnen eine Menge Ärger ersparen, da Sie nicht die ganze Sammlung reinstanziieren müssen, wenn sich eine von Hunderttausenden Eigenschaften darin ändert. Denken Sie daran, es in Ihrem Konstruktor zu initialisieren. :)

+1

Dies scheint so, als würde es viele potentiell unnötige Eigenschaftsänderungsereignisse auslösen, Ihre letzte Zeile OnPropertyChanged(); bewirkt, dass der aktuelle Datenkontext all seine Bindungen neu bewertet, was eine sehr teure Operation für ein tiefes oder großes Objektdiagramm sein könnte Mit einer ObservableCollection von ViewModels, die eine eigene Property-Benachrichtigung implementiert, wäre es besser, wenn Property-Änderungen nur dort isoliert werden, wo sie benötigt werden, zB http://StackOverflow.com/a/4040810/4490 – benPearce

+0

@benPearce Ich habe das letzte 'OnPropertyChanged 'bemerkt(); 'wird nur aufgerufen, wenn die Sammlung vollständig eingestellt ist, nicht bei Änderung des Elements. Die 'CollectionChanged() => OnPropertyChanged (Name von (MyCollection));' wäre, was alles bei jeder Änderung an der Sammlung aktualisiert wird.Wenn Ihre 'ListBox' oder' ListView' jedoch ein 'VirtualizingStackPanel' oder ähnliches verwendet, ist dies leider notwendig, um Änderungen in' DataTrigger's oder ähnlichem in den meisten Fällen sichtbar zu machen. Kleinere Listen mit insgesamt ~ 200k Bindungen auf ~ 20k Elemente ist aber noch in Ordnung. Kann aber nicht mehr sagen. – Jirajha

Verwandte Themen