Codefrak
Codefrak

Reputation: 13

Get a reference to the ObservableCollection that fired the change event

ObservableCollection<> exposes the CollectionChanged event. From the handler of that event is there any way to get a reference to the ObservableCollection that fired the event? I would have thought the sender argument would be the ObservableCollection but it's not.

This code sample illustrates that 10 ObservableCollections all have their CollectionChanged event registered to one method. From that one method I'd like to get the reference to the ObservableCollection that changed:

internal class Program
{
    private static void Main(string[] args)
    {
        List<ObservableCollection<int>> collections = new List<ObservableCollection<int>>();

        for (int i = 0; i < 10; i++)
        {
            ObservableCollection<int> collection = new ObservableCollection<int>();
            collection.CollectionChanged += CollectionOnCollectionChanged;
            collections.Add(collection);
        }

        collections[5].Add(1234);
    }

    private static void CollectionOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs)
    {
        if (notifyCollectionChangedEventArgs.Action == NotifyCollectionChangedAction.Add)
        {
            // Before proceeding I need to get a reference to the ObservableCollection<int> where the change occured which fired this event.
        }
    }
}

Looking at the arguments passed into the event handler, I don't see a reference to the ObservableCollection so I'm assuming I can't get it.

Upvotes: 0

Views: 1450

Answers (2)

Enigmativity
Enigmativity

Reputation: 117064

One other option you have is to use an in-line delegate and form a closure over the collection like this:

private static void Main(string[] args)
{
    List<ObservableCollection<int>> collections = new List<ObservableCollection<int>>();

    for (int i = 0; i < 10; i++)
    {
        ObservableCollection<int> collection = new ObservableCollection<int>();
        collection.CollectionChanged += (s, e) =>
        {
            if (e.Action == NotifyCollectionChangedAction.Add)
            {
                // Can reference `collection` directly here
            }
        };
        collections.Add(collection);
    }

    collections[5].Add(1234);
}

The saves casting from the sender object (which I find messy.)

A further way to write this could would be:

private static void Main(string[] args)
{
    List<ObservableCollection<int>> collections =
        Enumerable
            .Range(0, 10)
            .Select(n => new ObservableCollection<int>())
            .ToList();

    collections
        .ForEach(collection =>
        {
            collection.CollectionChanged += (s, e) =>
            {
                if (e.Action == NotifyCollectionChangedAction.Add)
                {
                    // Can reference `collection` directly here
                }
            };
        });

    collections[5].Add(1234);
}

Upvotes: 0

Sjoerd222888
Sjoerd222888

Reputation: 3476

The sender object is the instance of the ObservableCollection that fired the event. You can cast it.

 private static void CollectionOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs)
 {
     if (notifyCollectionChangedEventArgs.Action == NotifyCollectionChangedAction.Add)
     {
         ObservableCollection<int> myCollection = sender as ObservableCollection<int>;
         if(myCollection != null){
             //do whatever you want
         }
     }
 }

Upvotes: 1

Related Questions