INotifyCollectionChanged is not updating the UI

14,456

Solution 1

INotifyCollectionChanged has to be implemented by a collection class. Not by the class containing the collection.
You need to remove INotifyPropertyChanged from DataContextClass and add it to PersonCollection.

Solution 2

Instead of using IList use ObservableCollection<T> and define your PersonCollection class as below:

public class PersonCollection : ObservableCollection<Person>
{}

You can read more about ObservableCollection<T> class here which is designed specifically for collection change notifications in WPF DataBinding scenarios.

As you can see from the definition in MSDN below, it already implements INotifyCollectionChanged

public class ObservableCollection<T> : Collection<T>, 
    INotifyCollectionChanged, INotifyPropertyChanged

More articles to help you with usage of ObservableCollection class in WPF are below:

Create and Bind to an ObservableCollection
An introduction to ObservableCollection in Wpf
Databinding a ObservableCollection in MVVM

Share:
14,456
Vikram
Author by

Vikram

Working as Software developer. You can follow me on twitter here. and add me to your linked in profile

Updated on June 26, 2022

Comments

  • Vikram
    Vikram almost 2 years

    I have a class as shown below. All the functions I have removed for brevity

    public class PersonCollection:IList<Person>
    {}
    

    Now I have one more Model class as shown below. AddValueCommand is class deriving from ICommand which again I am omiting.

    public class DataContextClass:INotifyCollectionChanged
    {
        private PersonCollection personCollection = PersonCollection.GetInstance();
    
        public IList<Person> ListOfPerson
        {
            get 
            {
                return personCollection;
            }            
        }
    
        public void AddPerson(Person person)
        {
            personCollection.Add(person);
            OnCollectionChanged(NotifyCollectionChangedAction.Reset);
        }
    
    
        public event NotifyCollectionChangedEventHandler CollectionChanged = delegate { };
        public void OnCollectionChanged(NotifyCollectionChangedAction action)
        {
            if (CollectionChanged != null)
            {
                CollectionChanged(this, new NotifyCollectionChangedEventArgs(action));
            }
        }       
    
        ICommand addValueCommand;
    
        public ICommand AddValueCommand
        {
            get
            {
                if (addValueCommand == null)
                {
                    addValueCommand = new AddValueCommand(p => this.AddPerson(new Person { Name = "Ashish"}));
                }
                return addValueCommand;               
            }
        }
    }
    

    In the main window I am binding my UI to Model as shown below

     DataContextClass contextclass = new DataContextClass();           
     this.DataContext = new DataContextClass();
    

    And My UI looks like as shown below

    <ListBox Margin="5,39,308,113" ItemsSource="{Binding Path=ListOfPerson}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBox Height="20" Text="{Binding Path=Name}"></TextBox>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <Button Content="Button"  HorizontalAlignment="Left" Command="{Binding Path=AddValueCommand}" Margin="233,39,0,73" />
    

    My List Box is not updating with the new value when button is clicked. What I am missing here.

  • Vikram
    Vikram about 11 years
    Thanks a lot for the Answers, but here I have a doubt suppose if I dont want to change my PersonCollection, how can I achieve this by only doing the change at DataContextClass
  • Vikram
    Vikram about 11 years
    Thanks for the answer. But unfortunately I will not be able to do changes in PersonCollection.
  • Daniel Hilgarth
    Daniel Hilgarth about 11 years
    @Vikram: You can't. The WPF engine looks for that interface on the property that is bound to ItemsSource. It doesn't look for that interface on the data context.