views:

86

answers:

2

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

    } 
A: 

Try this

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

    }
 }

OR

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

    }
 }

Depending on your implementation.

VoodooChild
whenever a value is set to a property, the method “onPropertyChanged” will be called which in turn raises the PropertyChanged event.
VoodooChild
I don't understand. How does the PropertyChanged Event affect the CollectionChanged event of the collection when a new InventoryBTO is added?
Also how would you then access the properties inside the collection changed event which contain the new items added.
CollectionChanged event Occurs when an item is added, removed, changed, moved, or the entire list is refreshed.http://msdn.microsoft.com/en-us/library/ms653375.aspx
VoodooChild
Correct, so why when I add an item to the observable collection does the event not fire? Am I totally missing the point?
+2  A: 

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, your 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 surpressEvents = false;

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

    }

    protected override void OnCollectionChanged(System.Collections.Specialized.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...
} 
BFree