INotifyPropertyChange ~ 当属性是集合并且新项目添加到集合中时,PropertyChanged 不会触发
我有一个实现 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));
}
如果我分配一个新的 List
我正在考虑向我的类添加一个 AddAnswer() 方法,该方法将处理调用列表的 Add 方法,并从那里调用 onPropertyChanged() ,但这是正确的方法吗?有更优雅的方法吗?
干杯, 康泰
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您应该公开
ObservableCollection
,它实现 INotifyCollectionChange 接口来引发其自己的更改事件。您还应该删除属性设置器; 集合属性应为只读。
当集合的内容发生更改时,您不应引发
PropertyChanged
事件。You should expose an
ObservableCollection<string>
, which implements theINotifyCollectionChange
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.好吧,我终于遇到了这个问题,而且互联网上没有完整的答案,所以这里是没有人提到的缺失部分(也许是因为假设我们不是完全的白痴并且没有删除默认构造函数,或者已经alteast 扩展了默认构造函数)无论如何:
确保您没有删除 InitializeComponent();调用视图的构造函数。
如果在设置视图的 DataContext 之前没有此调用,NotifyPropertyChanged 事件将始终为 NULL。我花了大约 2 个小时试图弄清楚两个不同的 MVVM 用户控件之间有什么不同。我想我的头脑已经习惯了看到InitializeComponent();它没有登记它丢失了。我添加了后面和中提琴!
希望这能帮助像我这样的其他傻瓜!
干杯,
代码战士马洛
Ok I just finally experienced this issue, and there are NO complete answers on the Internet afaikt, so here is the missing piece that no one mentions (maybe because the assume that we are not complete morons and have NOT deleted the default constructor, or have alteast extended the default constructor) anyhow:
Make certain that you DID NOT delete the InitializeComponent(); call in the constructor of your View.
Without this call BEFORE you set DataContext of the view, NotifyPropertyChanged Event will ALWAYS BE NULL. I spent about 2 hours trying to figure out what was different between two different MVVM userControls. I guess my mind is so used to seeing InitializeComponent(); that it did not register that it was missing. I added that back and viola!
Hope This Helps Other Dummies Like Me!
Cheers,
Code Warrior Malo
它没有触发,因为集合引用没有改变,只是内容改变了。您需要集合的 Add() 方法来触发事件才能看到它。
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.
看一下 System.Collections.ObjectModel.ObservableCollection。 http://msdn.microsoft.com/en-us/library/ms668604。 aspx
它可以像列表一样使用,但内置了当其内容发生变化时的事件。
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.
ObservableCollection 就是你的答案。如果要触发集合属性更改,则需要为要跟踪的每个属性实现 INotifyPropertyChanged。
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.
您应该将事件侦听器添加到您的
_answers
集合中。不幸的是,List
不提供这样的事件。建议将
_answers
作为ObservableCollection
进行管理,并正确附加/分离CollectionChanged
事件的事件处理程序,如下所示: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 anObservableCollection<string>
, and properly attach/detach an event handler for theCollectionChanged
event, as follows: