Question

I am currently writing a Windows 8.1 app that uses MVVM. I've stayed away from the model simply because I have never properly been able to update the View when data bound to the View changes. No number of websites or tutorials have been able to explain how to properly use INotifyPropertyChanged and I'm just lost at this point. I have the following class (including the method for adding an item of that type).

public class Organization
{
    public Guid Id { get; set; }
    public bool IsShared { get; set; }
    public string Name { get; set; }
    public ObservableCollection<Event> Events { get; set; }

    public async static void Add(string Name)
    {
        Guid Id = Guid.NewGuid();
        string FileName = Id.ToString() + ".txt";
        var Folder = ApplicationData.Current.LocalFolder;

        try
        {
            var Organizations = await Folder.CreateFolderAsync("Organizations", CreationCollisionOption.FailIfExists);
            StorageFile File = await Organizations.CreateFileAsync(FileName, CreationCollisionOption.ReplaceExisting);
            await FileIO.WriteTextAsync(File, JsonConvert.SerializeObject(new Organization { Id = Id, Name = Name, Events=new ObservableCollection<Event>() }));
        }
        catch
        {

        }


    }
}

The following is my ViewModel:

public class OrganizationsViewModel : Base
{
    private ObservableCollection<Organization> _List = new ObservableCollection<Organization>();
    public ObservableCollection<Organization> List
    {
        get
        {
            Retrieve();
            return _List;
        }
        set
        {

        }
    }

    public async void Retrieve()
    {
        var Folder = ApplicationData.Current.LocalFolder;
        try
        {
            StorageFolder Organizations = await Folder.GetFolderAsync("Organizations");
            var List = await Organizations.GetFilesAsync();

            foreach (StorageFile i in List)
            {
                try
                {
                    using (Stream s = await i.OpenStreamForReadAsync())
                    {
                        using (StreamReader sr = new StreamReader(s))
                        {
                            var item = JsonConvert.DeserializeObject<Organization>(await sr.ReadToEndAsync());
                            _List.Add(item);
                        }
                    }
                }
                catch
                {

                }
            }
        }

        catch
        {

        }
    }
}

The Base being:

public class Base : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void NotifyPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
        {
            // property changed
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

What code do I need in my ViewModel and/or my class definition that will allow the View to properly update when items are added or removed from my ObservableCollection and more importantly why does that given code work? Thanks in advance!

Was it helpful?

Solution

With databinding View will automatically updated as long as it notified that properties it bound to has been changed. So what you need is to raise property changed event whenever binding source property value changed. For example :

public class OrganizationsViewModel : Base
{
    private ObservableCollection<Organization> _List = new ObservableCollection<Organization>();
    public ObservableCollection<Organization> List
    {
        get
        {
            Retrieve();
            return _List;
        }
        set
        {
            if(_List != value)
            {
                _List = value;
                NotifyPropertyChanged("List");
            }
        }
    }

    ...
    ...
}

However, ObservableCollection should automatically notify View whenever item added to or removed from collection without you raise the event manually. So I am not 100% sure where is the problem in your code. Just try to call NotifyPropertyChanged on setter of every property and see if the problem solved. At least you know how to use INotifyPropertyChanged now :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top