views:

224

answers:

5

I have a class that implements the INotifyPropertyChanged interface. Some of the properties of the class are of type List. For example:

public List<string> Answers
{
    get { return _answers;  }
    set
    {
      _answers = value;
      onPropertyChanged("Answers")
    }
}

...

private void onPropertyChanged(string propertyName)
{
    if(this.PropertyChanged != null)
        this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}

If I assign a new List<string> to Answer, then the PropertyChanged event fires as expected; but if I add a string string to the Answer list using the List Add method, then PropertyChanged event doesn't fire.

I was considering adding an AddAnswer() method to my class, which would handle calling the lists's Add method and would call onPropertyChanged() from there, but is that the right way to do it? Is there a more elegant way of doing it?

Cheers, KT

+1  A: 

It's not firing because the collection reference isn't changing, just the contents. You'd need the collection's Add() method to fire the event to be able to see it.

Josh Sterling
+4  A: 

You should expose an ObservableCollection<string>, which implements the INotifyCollectionChange interface to raise its own change events.

You should also remove the property setter; Collection properties should be read only.

You should not raise the PropertyChanged event when the contents of the collection change.

SLaks
Damn you folks are quick! This worked great, thanks!
eponymous23
Be sure to look through the unanswered questions and pay it forward by sharing your expertise. This site works because people give back.
William Leader
+1  A: 

have a look at System.Collections.ObjectModel.ObservableCollection. http://msdn.microsoft.com/en-us/library/ms668604.aspx

It can be used like a List but has events built in for when its contents change.

William Leader
A: 

ObservableCollection is your answer. If you want to fire on collection property changes, you'll need to implement INotifyPropertyChanged for each of the properties you'd like to track.

Robaticus
A: 

You should add an event listener to your _answers collection. Unfortunately, List<T> doesn't provide such an event.

As a suggestion, manage _answers as an ObservableCollection<string>, and properly attach/detach an event handler for the CollectionChanged event, as follows:

public ObservableCollection<string> Answers
{
    get { return _answers;  }
    set
    {
      // Detach the event handler from current instance, if any:
      if (_answers != null)
      {
         _answers.CollectionChanged -= _answers_CollectionChanged;
      }

      _answers = value;

      // Attatach the event handler to the new instance, if any:
      if (_answers != null)
      {
         _answers.CollectionChanged += _answers_CollectionChanged;
      }

      // Notify that the 'Answers' property has changed:
      onPropertyChanged("Answers");
    }
}

private void _answers_CollectionChanged(object sender,
NotifyCollectionChangedEventArgs e)
{
   onPropertyChanged("Answers");
}
Humberto