2008-11-17 8 views
5

El evento ListChanged para una IBindingList desencadena un tipo ListChangedType.ItemDeleted cuando se eliminan elementos, tal vez por un usuario que elimina una fila en un control de cuadrícula de datos vinculado a la lista. El problema es que NewIndex en la lista no es válido en este caso, se ha eliminado y el elemento eliminado no está disponible. Debería haber un evento de eliminación de elementos, pero dudo que alguna vez arreglen esto.dotnet: ListChangedType.ItemDeleted es inútil?

Respuesta

8

Sí, es bastante molesto, pero hay una solución fácil. Creo una clase BindingListBase<T> que utilizo para todas mis listas en lugar de utilizar un BindingList<T> normal. Como mi clase hereda del BindingList<T>, tengo acceso a todos sus miembros protegidos, incluido el método RemovedItem.

Esto me permite recoger cuando se elimina un artículo. Podrías hacer lo que hago y tener una lista mRemovedItems a la que siempre agrego elementos, o plantear tu propio evento 'ItemRemoved'.

Ver mi ejemplo de código siguiente:

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 
2

No es realmente para ese propósito. NewIndex es el índice donde estaba el elemento cuando se eliminó, y es útil para que los controles enlazados puedan ubicar su elemento de visualización asociado en sus propias listas y eliminarlo.

¿Cuál es el caso de uso que desea habilitar con un ItemDeleting?

1

me hizo algo similar a lo que hizo Adam Valpied, es decir implementado mi propia clase con un ListChanging controlador de eventos. Eso me permite trabajar con el elemento que está a punto de eliminarse de la lista antes de que realmente lo haga.

En respuesta a la pregunta de Sunlight sobre el caso de uso ... entre otras cosas, lo uso para eliminar los controladores de eventos que se colocaron en el elemento contenido cuando se puso en la lista. Mis elementos de datos contienen un nivel de gravedad de error, determinado durante la validación, y los elementos de la GUI están obligados a mostrar esa severidad de error como un color de fondo. Cuando el nivel de severidad de error del elemento de datos cambia, el elemento GUI debe actualizarse. Así que tengo que poner un controlador de eventos HighestSeverityChanged en el elemento de datos cuando se muestra (ya sea por sí mismo o como parte de una lista que se muestra), y necesito eliminar ese controlador de eventos cuando el elemento GUI está libre del elemento de datos.

2

Aquí es mi versión de una clase que implementa BindingList un evento ItemRemoved, en lugar de mantener una lista secundaria de los elementos eliminados

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)); 
    } 
} 
Cuestiones relacionadas