ObservableCollection 和 CollectionChanged 事件

5
为什么以下代码中的collectionchanged事件没有触发,但我可以看到我添加到ObservableCollection中的新InventoryBTO实例?
 private ObservableCollection<InventoryBTO> _inventoryRecords;
    public ObservableCollection<InventoryBTO> InventoryRecords
    {
        get { return _inventoryRecords; }
        set { _inventoryRecords = value; }
    }

    private InventoryBTO _selectedRecord;
    public InventoryBTO SelectedRecord
    {
        get { return _selectedRecord; }
        set 
        {
            if (_selectedRecord != value)
            {
                _selectedRecord = value;
                OnPropertyChanged(new PropertyChangedEventArgs("SelectedRecord"));
            }
        }
    }

    public InventoryViewModel()
    {
        if (_inventoryRecords == null)
        {
            InventoryRecords = new ObservableCollection<InventoryBTO>();
            this.InventoryRecords.CollectionChanged += new NotifyCollectionChangedEventHandler(InventoryRecords_CollectionChanged);
        }

        _inventoryRecords = InventoryListBTO.GetAllInventoryRecords();
    }

    void InventoryRecords_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {

    } 

1
看起来你在构造函数中连接到了集合,然后立即用完全不同的集合覆盖了引用。也许你本来想做的是添加范围而不是覆盖?无论如何,你创建并连接的可观察集合早已不存在了。 - James Manning
2个回答

10
问题在于你正在将私有成员分配给从方法中获取的一个新实例的 ObservableCollection。 因此,现在发生的情况是,你连接到一个集合的事件,但随后却使用一个你从未连接事件处理程序的新实例替换了它。以下是你可以做的。创建一个从ObservableCollection继承并添加addrange方法的类:
public class RangeObservableCollection<T> : ObservableCollection<T>
{
    private bool supressEvents = false;

    public void AddRange(IEnumerable<T> items)
    {
        supressEvents = true;
        foreach (var item in items)
        {
            base.Add(item);
        }
        this.supressEvents = false;
        this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, items.ToList()));

    }

    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        if (!this.surpressEvents)
        {
            base.OnCollectionChanged(e);
        }
    }
}

然后,你可以将你的类更改为以下内容:

private RangeObservableCollection<InventoryBTO> _inventoryRecords;
public RangeObservableCollection<InventoryBTO> InventoryRecords
{
    get { return _inventoryRecords; }
    set { _inventoryRecords = value; }
}

private InventoryBTO _selectedRecord;
public InventoryBTO SelectedRecord
{
    get { return _selectedRecord; }
    set 
    {
        if (_selectedRecord != value)
        {
            _selectedRecord = value;
            OnPropertyChanged(new PropertyChangedEventArgs("SelectedRecord"));
        }
    }
}

public InventoryViewModel()
{
    if (_inventoryRecords == null)
    {
        InventoryRecords = new ObservableCollection<InventoryBTO>();
        this.InventoryRecords.CollectionChanged += new NotifyCollectionChangedEventHandler(InventoryRecords_CollectionChanged);
    }

    this.InventoryRecords.AddRange(InventoryListBTO.GetAllInventoryRecords());
}

void InventoryRecords_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    //e.NewItems will be an IList of all the items that were added in the AddRange method...
} 

第一行指出了我的问题。所以我在属性的setter上添加了CollectionChanged事件处理程序。 - Ajeeb.K.P

0

试试这个

public ObservableCollection<InventoryBTO> InventoryRecords
{
    get { return _inventoryRecords; }
    set 
    { 
      _inventoryRecords = value; 
      onPropertyChanged(this, "InventoryRecords");

    }
 }

或者

public ObservableCollection<InventoryBTO> InventoryRecords
{
    get { return _inventoryRecords; }
    set 
    { 
      _inventoryRecords = value; 
      OnPropertyChanged(new PropertyChangedEventArgs("InventoryRecords"));

    }
 }

根据您的实现情况而定。

每当一个值被设置到属性中时,方法“onPropertyChanged”将被调用,从而引发PropertyChanged事件。 - VoodooChild
我不明白。当添加新的InventoryBTO时,PropertyChanged事件如何影响集合的CollectionChanged事件? - user337816
另外,您如何在修改事件中访问包含新添加项的集合中的属性? - user337816
1
CollectionChanged事件会在添加、移除、更改、移动或整个列表刷新时发生。 - VoodooChild
正确,那么为什么当我向可观察集合添加一个项目时,事件不会触发?我完全错过了重点吗? - user337816

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接