ObservableCollection and CollectionChanged Event

20,237

The problem is that you're assigning your private member to a new instance of an ObservableCollection that you're getting back from your method. Therefore, what's happening is, you're hooking up to the event of one collection, but then blowing away that instance and replacing it with a new instance you never hooked up an event handler to. Here's what you can do. Create a class that inherits from ObservableCollection and adds an addrange method:

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

Then, you can change your class to this:

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...
} 
Share:
20,237
user337816
Author by

user337816

Updated on March 08, 2020

Comments

  • user337816
    user337816 over 4 years

    Why does the collectionchanged event not fire in the following code, yet I can see the new instance of InventoryBTO I add to the ObservableCollection?

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