INotifyPropertyChange~当属性是一个集合并且一个新项目被添加到集合时,PropertyChanged不会触发

时间:2010-06-07 17:38:12

标签: c# inotifypropertychanged

我有一个实现INotifyPropertyChanged接口的类。该类的一些属性是List类型。例如:

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

如果我指定一个新列表&lt; string&gt;回答,然后PropertyChanged事件按预期触发;但是如果我使用List Add方法将一个字符串字符串添加到Answer列表中,那么PropertyChanged事件就不会触发。

我正在考虑在我的类中添加一个AddAnswer()方法,该方法将处理调用列表的Add方法并从那里调用onPropertyChanged(),但这是正确的方法吗?有更优雅的方式吗?

干杯, KT

6 个答案:

答案 0 :(得分:17)

您应该公开ObservableCollection<string>,它实现INotifyCollectionChange接口以引发自己的更改事件。

您还应该删除属性设置器; Collection properties should be read only

当集合的内容发生变化时,不应该引发PropertyChanged事件。

答案 1 :(得分:3)

好的我终于遇到了这个问题,并且在互联网上没有完整的答案,所以这里是没有人提到的缺失部分(也许是因为假设我们不是完整的笨蛋并且没有删除默认的构造函数,或者让alteast扩展默认构造函数)无论如何:

确保您不删除InitializeComponent();在视图的构造函数中调用。

如果没有此调用,则在设置视图的DataContext之前,NotifyPropertyChanged事件将始终为NULL。我花了大约2个小时试图弄清楚两个不同的MVVM用户控件之间有什么不同。我想我的心思已经习惯了看InitializeComponent();它没有记录它丢失了。我补充说回来了,中提琴!

希望这有助于像我这样的其他假人! 干杯, Code Warrior Malo

答案 2 :(得分:1)

它没有触发,因为集合引用没有改变,只是内容。你需要集合的Add()方法来激活事件才能看到它。

答案 3 :(得分:1)

查看System.Collections.ObjectModel.ObservableCollection。 http://msdn.microsoft.com/en-us/library/ms668604.aspx

它可以像List一样使用,但在内容发生变化时内置了事件。

答案 4 :(得分:0)

ObservableCollection是你的答案。如果要触发集合属性更改,则需要为要跟踪的每个属性实现INotifyPropertyChanged。

答案 5 :(得分:0)

您应该为_answers集合添加一个事件监听器。不幸的是,List<T>没有提供此类事件。

作为建议,将_answers作为ObservableCollection<string>进行管理,并正确附加/分离CollectionChanged事件的事件处理程序,如下所示:

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