Search code examples
c#.netcollections

Custom CollectionChanged event handler in C#


I have a collection in which items can be added or removed. I want to specify a reason whenever collection is modified. Is it possible, if yes what would be best way to achieve that?

List<string> names = new List<string>();
names.Remove("Adam", "FilteredDueTo4CharsInName");

I tried CollectionChangedEvent but I can not pass reasons into that.


Solution

  • Usually when you want to listen to events on a collection, you would use an ObservableCollection. It raises a CollectionChanged event.

    https://learn.microsoft.com/en-us/dotnet/api/system.collections.objectmodel.observablecollection-1?view=net-7.0

    However, in order to pass the custom data you might be better off using a wrapper on a List. Add your custom event to it and the Add method with the extra parameter:

        internal class CustomEventList<T> 
        {
            private List<T> _list = new List<T>();
    
            public event CollectionChangedEventHandler CollectionChanged;
    
            public void Add(T item, string reason)
            {
                ((ICollection<T>)_list).Add(item);
                CollectionChanged?.Invoke(this, new CollectionChangedEventArgs { Reason = reason });
            }
            //...etc..
        }
    }
    

    Delegate and eventargs for the event in the above:

    internal class  CollectionChangedEventArgs : EventArgs
    {
        internal string Reason;
    }
    
    internal delegate void CollectionChangedEventHandler(object sender, CollectionChangedEventArgs e);
    

    Another alternative would be to extend the List class. You would define a similar delegate and methods in that case. From what you say, the wrapper approach is probably preferable because in that case methods that change the collection without raising the event do not need to be exposed.