Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

dotnet: ListChangedType.ItemDeleted is useless?

The ListChanged event for an IBindingList fires a type ListChangedType.ItemDeleted when items are deleted, perhaps by a user deleting a row in a datagrid control bound to the list. The problem is that the NewIndex into the list is invalid in this event, it's been deleted, and the item that was deleted is not available. There should be an ItemDeleting event, but I doubt they will ever fix this.

like image 335
P a u l Avatar asked Nov 17 '08 08:11

P a u l


3 Answers

Yeah it's pretty annoying, but there is an easy workaround. I create a BindingListBase<T> class that I use for all of my lists instead of using a normal BindingList<T>. Because my class inherits from the BindingList<T>, I have access to all of it's protected members, including the RemovedItem method.

This enables me to pick up when an item is removed. You could do what I do and have a mRemovedItems list that I always add items to, or raise your own 'ItemRemoved' event.

See my code example below:

Public MustInherit Class BindingListBase(Of T)
    Inherits BindingList(Of T)

    Protected mRemovedItems As New List(Of T)

    Protected Overrides Sub ClearItems()
        MyBase.ClearItems()
        mRemovedItems.Clear()
    End Sub

    Protected Overrides Sub RemoveItem(ByVal index As Integer)
        Dim item As T = MyBase.Item(index)

        MyBase.RemoveItem(index)

        mRemovedItems.Add(item)
    End Sub

    Public ReadOnly Property RemovedItems as List(Of T)
        Get
            Return mRemovedItems
        End Get
    End Property
End Class
like image 52
Adam Valpied Avatar answered Nov 04 '22 00:11

Adam Valpied


It's not really intended for that purpose. NewIndex is the index where the item was when it was deleted, and it's useful for bound controls to be able to locate their associated display item in their own lists and remove that.

What is the use case you want to enable with an ItemDeleting?

like image 2
Sunlight Avatar answered Nov 04 '22 01:11

Sunlight


Here is my version of a BindingList class that implements an ItemRemoved event, rather than keeping a secondary list of deleted items

public class ItemRemovedEventArgs : EventArgs
{
    public Object Item { get; set; }

    public ItemRemovedEventArgs(Object item)
    {
        this.Item = item;
    }
}

public delegate void ItemRmoveEventHandler(Object sender, ItemRemovedEventArgs e);

public class BindingListRedux<T> : BindingList<T>
{
    public BindingListRedux() : base() { }

    public BindingListRedux(IList<T> list) : base(list) { }

    public event ItemRmoveEventHandler ItemRemoved;

    protected void OnItemRemoved(ItemRemovedEventArgs e)
    {
        if (ItemRemoved != null)
        {
            ItemRemoved(this, e);
        }
    }

    protected override void RemoveItem(int index)
    {
        Object item = base[index];
        base.RemoveItem(index);
        this.OnItemRemoved(new ItemRemovedEventArgs(item));
    }
}
like image 2
BenCamps Avatar answered Nov 04 '22 02:11

BenCamps