Extension to BindingList that allows for cancelable notifications of changing and deleting This is an extension of the System.ComponentModel.BindingList&lt;T&gt; class that allows for notifications of item changing and deleting. These notifications provided the outgoing item and the incoming item, as well as a Cancel property to cancel the change or deletion.

In additon, it also allows for a bulk addition of items, which is just a loop of AddItem (which will trigger a change notification for each item added).

On top of bulk addition, there is a SetItems which will clear the collection and add all the items provided, but will only fire one Reset notification.

using System;
using System.Collections.Generic;
using System.ComponentModel;

namespace BindingListExtension
{
    public class BindingListEx&lt;T&gt; : BindingList&lt;T&gt;
    {
        public event EventHandler&lt;ListItemRemovingEventArgs&lt;T&gt;&gt; ListItemRemoving;
        public event EventHandler&lt;ListItemChangingEventArgs&lt;T&gt;&gt; ListItemChanging;

        protected override void RemoveItem(int index)
        {
            var args = new ListItemRemovingEventArgs&lt;T&gt;(this[index], index);
            ListItemRemoving?.Invoke(this, args);
            if (args.Cancel) return;
            base.RemoveItem(index);
        }

        protected override void SetItem(int index, T item)
        {
            var args = new ListItemChangingEventArgs&lt;T&gt;(this[index], item, index);
            ListItemChanging?.Invoke(this, args);
            if (args.Cancel) return;
            base.SetItem(index, item);
        }

        public void SetItems(IEnumerable&lt;T&gt; items)
        {
            RaiseListChangedEvents = false;
            Clear();
            AddItems(items);
            RaiseListChangedEvents = true;
            OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
        }

        public void AddItems(IEnumerable&lt;T&gt; items)
        {
            if (items != null)
            {
                foreach (T item in items)
                {
                    Add(item);
                }
            }
        }
    }

    public class ListItemRemovingEventArgs&lt;T&gt; : CancelEventArgs
    {
        public ListItemRemovingEventArgs(T oldItem, int index)
        {
            OldItem = oldItem;
        }

        public T OldItem { get; }

        public int Index { get; }
    }

    public class ListItemChangingEventArgs&lt;T&gt; : ListItemRemovingEventArgs&lt;T&gt;
    {
        public ListItemChangingEventArgs(T oldItem, T newItem, int index) : base(oldItem, index)
        {
            NewItem = newItem;
        }

        public T NewItem { get; }
    }
}
ListChangedType.Reset

AddItems is nothing more than a glorified wrapper method for calling Add multiple times. However, guidelines suggest that ListChangedType.Reset could and probably should also be called here. Since Reset should be called when..


  Much of the list has changed. Any listening controls should refresh
  all their data from the list.


To give this method some purpose other than looping elements and call Add, consider using the same deferral strategy as you did with SetItems.