本文介绍了ObservableCollection 没有注意到其中的 Item 何时更改(即使使用 INotifyPropertyChanged)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有谁知道为什么这段代码不起作用:

Does anyone know why this code doesn't work:

public class CollectionViewModel : ViewModelBase {
    public ObservableCollection<EntityViewModel> ContentList
    {
        get { return _contentList; }
        set
        {
            _contentList = value;
            RaisePropertyChanged("ContentList");
            //I want to be notified here when something changes..?
            //debugger doesn't stop here when IsRowChecked is toggled
        }
     }
}

public class EntityViewModel : ViewModelBase
{

    private bool _isRowChecked;

    public bool IsRowChecked
    {
        get { return _isRowChecked; }
        set { _isRowChecked = value; RaisePropertyChanged("IsRowChecked"); }
    }
}

ViewModelBase 包含 RaisePropertyChanged 等的所有内容,它适用于除此问题之外的所有其他内容..

ViewModelBase containts everything for RaisePropertyChanged etc. and it's working for everything else except this problem..

推荐答案

当您更改集合内的值时,不会调用 ContentList 的 Set 方法,您应该注意 CollectionChanged 事件触发.

The ContentList's Set method will not get called when you change a value inside the collection, instead you should be looking out for the CollectionChanged event firing.

public class CollectionViewModel : ViewModelBase
{
    public ObservableCollection<EntityViewModel> ContentList
    {
        get { return _contentList; }
    }

    public CollectionViewModel()
    {
         _contentList = new ObservableCollection<EntityViewModel>();
         _contentList.CollectionChanged += ContentCollectionChanged;
    }

    public void ContentCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        //This will get called when the collection is changed
    }
}

好的,今天已经两次了,我被 MSDN 文档的错误所困扰.在我给你的链接中,它说:


Okay, that's twice today I've been bitten by the MSDN documentation being wrong. In the link I gave you it says:

在添加、删除项目时发生,更改、移动或整个列表被刷新了.

但它实际上不会在更改项目时触发.我想你需要一个更暴力的方法:

But it actually doesn't fire when an item is changed. I guess you'll need a more bruteforce method then:

public class CollectionViewModel : ViewModelBase
{
    public ObservableCollection<EntityViewModel> ContentList
    {
        get { return _contentList; }
    }

    public CollectionViewModel()
    {
         _contentList = new ObservableCollection<EntityViewModel>();
         _contentList.CollectionChanged += ContentCollectionChanged;
    }

    public void ContentCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.Action == NotifyCollectionChangedAction.Remove)
        {
            foreach(EntityViewModel item in e.OldItems)
            {
                //Removed items
                item.PropertyChanged -= EntityViewModelPropertyChanged;
            }
        }
        else if (e.Action == NotifyCollectionChangedAction.Add)
        {
            foreach(EntityViewModel item in e.NewItems)
            {
                //Added items
                item.PropertyChanged += EntityViewModelPropertyChanged;
            }
        }
    }

    public void EntityViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        //This will get called when the property of an object inside the collection changes
    }
}

如果你非常需要这个,你可能想要子类化你自己的 ObservableCollection,当成员触发它的 PropertyChanged 时它会触发 CollectionChanged 事件code> 事件自动(就像它在文档中说的那样......)

If you are going to need this a lot you may want to subclass your own ObservableCollection that triggers the CollectionChanged event when a member triggers its PropertyChanged event automatically (like it says it should in the documentation...)

这篇关于ObservableCollection 没有注意到其中的 Item 何时更改(即使使用 INotifyPropertyChanged)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-31 22:52