c# - ¿Qué causa un evento ListChangedType.ItemMoved ListChange en una BindingList<T>?
events (3)
Tengo un BindingList (T) que estoy mostrando en un DataGrid . Estoy mirando eventos ListChanged y realizando diferentes acciones cuando se evoca el evento ListChanged .
Estoy comprobando el argumento del evento ListChangeType para comprobar cómo se modificó la lista, y luego responder en consecuencia. Sin embargo, noté que hay un tipo de evento ListChanged 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 parezca mover un elemento en 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
}
}
Se desencadena si la fuente de enlace tiene una ordenación aplicada, si cambia y los datos que se mantienen en el campo de ordenamiento y luego cambia la posición de la grabación, se desencadena el evento.
De forma similar a la respuesta de Scott, podrías 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 ItemMoved que buscaba, pero guarda la 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 ...
Desafortunadamente, nada en BindingList generará 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 derivar 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 debe ilustrar los puntos principales.