我注意到在向ViewModel属性添加对象时,RaisePropertyChanged会出现奇怪的行为。
private List<string> _items;
public List<string> Items
{
get
{
if(_items == null){ _items = new List<string>(); }
return _itmes;
}
set
{
_items = value;
RaisePropertyChanged("Items");
}
}
我什么时候通过属性
将对象添加到集合中Items.Add("new string");
永远不会调用RaisePropertyChanged。
让RaisePropertyChanged按照我希望的方式运行的最佳方法是什么?
答案 0 :(得分:5)
更改集合时将调用您的setter,而不是在更改集合的内容时调用。
您需要的是一个通知您变化的集合。看看ObservableCollection<T>
- 班级。注册参加CollectionChanged活动,了解变更情况。
带有二传手的属性
以下示例显示如何使用包含可观察集合的可设置属性。该示例的复杂性是因为可以从实例的外部设置集合。如果您不需要此功能,解决方案将变得更加简单。
private ObservableCollection<string> _items;
public ObservableCollection<string> Items {
get {
if (_items == null) {
// Create a new collection and subscribe to the event
Items=new ObservableCollection<string>();
}
return _items;
}
set {
if(value !=_items){
if (null != _items) {
// unsubscribe for the old collection
_items.CollectionChanged -= new System.Collections.Specialized.NotifyCollectionChangedEventHandler(_items_CollectionChanged);
}
_items = value;
if (null != _items) {
// subscribe for the new collection
_items.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(_items_CollectionChanged);
}
// Here you will be informed, when the collection itselfs has been changed
RaisePropertyChanged("Items");
}
}
}
void _items_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) {
// Here you will be informed, if the content of the collection has been changed.
}
没有二传手的属性
如果您不需要将集合设置为setable,请在创建集合时注册CollectionChanged
。但是,您必须删除属性的setter。如果收集已更改,则不会通知更改:
private ObservableCollection<string> _items;
public ObservableCollection<string> Items {
get {
if (_items == null) {
// Create a new collection and subscribe to the event
_items=new ObservableCollection<string>();
_items.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler
}
return _items;
}
}
void _items_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) {
// Here you will be informed, if the content of the collection has been changed.
}
其他信息
有关集合更改的更多信息,请查看INotifyCollectionChanged 。以上示例您还可以使用IEnumerable<string>
和INotifyCollectionChanged
更加通用。
答案 1 :(得分:2)
当然,它永远不会被调用,因为当您向集合中添加项目时,实际上并未设置属性(未调用Items属性的setter)。
如果是集合修改,您需要的是引发CollectionChanged事件。为此,您需要使用ObservableCollection<T>
而不是通常List<T>
:
private ObservableCollection<string> _items;
public ObservableCollection<string> Items
{
get
{
if(_items == null){ _items = new ObservableCollection<string>(); }
return _itmes;
}
set
{
_items = value;
RaisePropertyChanged("Items");
}
}
现在,当您向集合添加项目时,将引发CollectionChanged
事件,并且您的UI将相应地更新。