Missing RemovedItem from BindingList and BindingSource

If you work with Windows Forms you cannot live without binding :D, but something is missing from the base structure. I want to create a simple form with a BindingSource, then bind a list of object to a grid and some textboxes to create a master detail form, moreover I set up a simple navigator to make simple for the user navigating the structure, the navigator has the addnew and remove button and the user likes them.

The user can Add and Remove element from the navigator, or directly from a DataGridView, and I simply need to call the appropriate method of Repository to save and delete objects. This structure is really clean, but you encounter a problem: nor the BindingSource nor the BindingList<T> raises a RemovingItem event. I do not know why these classes are designed in this way, you have an AddingNew Event in the Binding Source and BindingList<T> but no corresponding RemovingItem. You have a ListChanged event that tells you when an element is removed, but the element is already gone from the list, so you cannot use to detect object removal.

If you look at the events of BindingList<T> you can notice that there is no way to be informed of the exact element that gets removed. A simple solution is to inherit from the BindingList<T>

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class RemoveItemEventArgs : EventArgs
{
    public Object RemovedItem
    {
        get { return removedItem;}
    }
    private Object removedItem;
    public RemoveItemEventArgs(object removedItem)
    {
        this.removedItem = removedItem;
    }
}
public class MyBindingList<T> : BindingList<T>
{
    public event EventHandler<RemoveItemEventArgs> RemovingItem;
    protected virtual void OnRemovingItem(RemoveItemEventArgs args)
    {
        EventHandler<RemoveItemEventArgs> temp = RemovingItem;
        if (temp != null)
        {
            temp(this, args);
        }
    }
    protected override void RemoveItem(int index)
    {
        OnRemovingItem(new RemoveItemEventArgs(this[index]));
        base.RemoveItem(index);
    }
    public MyBindingList(IList<T> list) : base(list)
    {
    }
    public MyBindingList()
    {
    }
}

As you can see implementing such a functionality is a breeze, you should simply override the RemoveItem method and raise a custom RemovingItem event. Now I can use this new BindingList in this way.

1
2
3
4
5
MyBindingList<UIDomainProxy> source = new MyBindingList<UIDomainProxy>(
    Repository<Domain>.GetAll().Select(d => new UIDomainProxy(d)).ToList());
source.AddingNew +=source_AddingNew;
source.RemovingItem +=source_RemovingItem;
domainBindingSource.DataSource = source;

I gets all the element from the repository, then I wrap then in a UIProxy (I’ll explain this in a future post), then I intercept the addingNew and RemovingItem events simply calling Save and Delete methods from the repository. Finally I set the BindingList as the source of the BindingSource created by the designer.

I wonder why this event is missing from the basic BindingList<T> implementation.

alk.

Tags: ” rel=tag>BindingList .NET Binding Windows Forms