2009-08-06 14 views
11

Tengo BindingList (T) que estoy mostrando en un DataGrid. Estoy viendo ListChanged eventos y realizando diferentes acciones cuando se evoca el evento ListChanged.¿Qué causa un evento ListChangedType.ItemMoved ListChange en una BindingList <T>?

Estoy revisando el ListChangeType argumento del evento para comprobar cómo se modificó la lista, y luego responder en consecuencia. Sin embargo, me di cuenta de que hay ListChanged tipo de evento ItemMoved.

Tengo botones para "Mover hacia arriba" y "Mover hacia abajo" para mover los elementos hacia arriba y hacia abajo en la lista. Pero estos en realidad están eliminando el elemento seleccionado y luego reinsertándolo en una posición más alta o más baja. Sin embargo, no veo ningún método de BindingList (T) que parece que movería un elemento de la lista. Entonces, ¿me estoy perdiendo algo o simplemente no hay forma de mover un elemento en un BindingList que también evoca un evento ItemMoved tipo ListChanged?

void FloorCollection_ListChanged(object sender, ListChangedEventArgs e) 
{ 
    if (e.ListChangedType == ListChangedType.ItemAdded) 
    {  
     //DO STUFF 
    } 
    else if (e.ListChangedType == ListChangedType.ItemDeleted) 
    { 
     //DO STUFF 
    } 
    else if (e.ListChangedType == ListChangedType.ItemMoved) 
    { 
     //HOW DO I GET THIS CODE TO RUN? 
    } 
    else if (e.ListChangedType == ListChangedType.ItemChanged) 
    { 
     //DO STUFF 
    } 
} 

Respuesta

9

Por desgracia, no hay nada en BindingList levantará un evento ListChanged con ListChangedType establecido en ListChangedType.ItemMoved. BindingList hereda de Collection que no proporciona ningún tipo de soporte para elementos "en movimiento" en la lista. BindingList no agrega ningún soporte para este tipo de comportamiento tampoco.

Si realmente necesita/desea responder a los eventos ListChangedType.ItemMoved su mejor opción es obtener su propia clase de BindingList y proporcionar sus propios métodos Move. Dentro de esos métodos, debe suspender temporalmente la generación de eventos ListChanged, realizar el movimiento mediante la eliminación/adición, elevar el evento ListChanged usted mismo con el ItemMoved ListChangedType apropiado, y luego revertir la suspensión de subir eventos ListChanged.

se vería algo como esto *:

public class CustomBindingList<T> : BindingList<T> 
{ 
    public void Move(T item, int index) 
    { 
     bool raiseListChangedEvents = this.RaiseListChangedEvents; 
     try 
     { 
     this.RaiseListChangedEvents = false; 
     int oldIndex = this.IndexOf(item); 
     this.Remove(item); 
     this.InsertItem(index, item);  
     this.OnListChanged(new ListChangedEventArgs(ListChangedType.ItemMoved, index, oldIndex)); 
     } 
     finally 
     { 
     this.RaiseListChangedEvents = raiseListChangedEvents; 
     } 
    } 
} 

* Código totalmente no probado, pero debería ilustrar los puntos principales.

+4

Los puntos principales parecen correctos, solo pensé que debería señalar que mover un elemento a un índice más bajo no funcionará con este código: el this.Remove (item) cambiará los índices. Por lo menos, inserte el elemento una sola vez; en el peor, intente insertar más allá del final de la lista. – Yoopergeek

1

Se activa si la fuente de enlace tiene una ordenación aplicada, si cambia y los datos que se mantienen en el campo de clasificación y luego cambia la posición de la grabación, se activa el evento.

1

En una línea similar a la respuesta de Scott, que podría hacer algo como este método de extensión:

//Dumping ground for miscellaneous functions 
public static class Misc 
{ 
    //Swap items at index positions 'index0' and 'index1' in the list 
    public static void Swap<T>(this BindingList<T> list, int index0, int index1, bool reset_bindings) 
    { 
     if (index0 == index1) return; 
     bool raise_events = list.RaiseListChangedEvents; 
     try 
     { 
     list.RaiseListChangedEvents = false; 
     T tmp = list[index0]; 
     list[index0] = list[index1]; 
     list[index1] = tmp; 
     list.RaiseListChangedEvents = raise_events; 
     if (reset_bindings) list.ResetBindings(); 
     } 
     finally 
     { 
     list.RaiseListChangedEvents = raise_events; 
     } 
    } 
}

Esto no produce los eventos que fueron después ItemMoved pero ahorra tener que subclase BindingList <>. Puede subir el evento Restablecer (usando Reiniciar Vinculaciones()) una vez que haya terminado de mover los elementos de la lista. Podría ser útil ...

Cuestiones relacionadas