user3631797
user3631797

Reputation: 35

INotifyPropertyChanged is not working MVVM

I have an Observable collection, but after updating the collecion, my Listview is not updating even after raising Property Changed event see below code:-

Look below 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>

Look below Class

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

I am calling this way

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

Upvotes: 0

Views: 1021

Answers (2)

benPearce
benPearce

Reputation: 38333

Add the following using statements:

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

Change your VideoGroupList line to:

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

This better utilises the change notification built into the ObservableCollection

Upvotes: 1

Jirajha
Jirajha

Reputation: 493

According to the MSDN Documentation, CollectionChanged will be raised on adding, removing and changing an element in an ObservableCollection. I found this not to be the case however. ObservableCollection.CollectionChanged will only be thrown on add/remove. I use this FullyObservableCollection here instead, with the modification to have T be my ViewModelBase class instead of INotifyPropertyChanged directly.

When I declare my Property then, I use a snippet with the following output: 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(); } } This way you will always have INotifyPropertyChanged Notifications on Add, Remove, Replace and Change action on the collections and every single one of its members. It will save you a lot of hassle since you do not need to reinstanciate the whole collection if one of hundreds of thousands properties in it changes. Remember to initialize it in your constructor though. :)

Upvotes: 0

Related Questions