2009-08-06 4 views
11

J'ai une BindingList (T) que j'affiche dans un DataGrid. Je surveille les événements ListChanged et effectue différentes actions lorsque l'événement ListChanged est appelé.Qu'est-ce qui provoque un événement ListChanged ListChangedType.ItemMoved dans un BindingList <T>?

Je vérifie l'argument ListChangeType de l'événement pour vérifier comment la liste a été modifiée, puis répondre en conséquence. Cependant, j'ai remarqué qu'il y a un ListChanged type d'événement ItemMoved.

J'ai des boutons pour "Monter" et "Déplacer vers le bas" pour déplacer des éléments de haut en bas de la liste. Mais ils suppriment en fait l'élément sélectionné, puis le réinsèrent dans une position plus haute ou plus basse.

Cependant, je ne vois aucune méthode de BindingList (T) qui semble déplacer un élément de la liste. Est-ce qu'il me manque quelque chose ou est-ce qu'il n'y a aucun moyen de déplacer un élément dans une BindingList qui évoquerait aussi un événement ListChanged de type ItemMoved?

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 
    } 
} 

Répondre

9

Malheureusement, rien dans BindingList soulèvera un événement ListChanged avec ListChangedType mis à ListChangedType.ItemMoved. BindingList hérite de Collection qui ne fournit aucun type de support pour "déplacer" des éléments de la liste. BindingList n'ajoute aucun support pour ce type de comportement non plus.

Si vous avez vraiment besoin de répondre aux événements ListChangedType.ItemMoved, votre meilleure option est de dériver votre propre classe de BindingList et de fournir vos propres méthodes de déplacement. À l'intérieur de ces méthodes, vous devez suspendre temporairement l'élévation des événements ListChanged, effectuer le déplacement en supprimant/ajoutant, déclencher vous-même l'événement ListChanged avec le ListChangedType ItemMoved approprié, puis rétablir la suspension de l'augmentation des événements ListChanged.

Il ressemblerait à quelque chose comme ça *:

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; 
     } 
    } 
} 

* Code totalement non testé, mais il devrait illustrer les points principaux.

+4

Les points principaux semblent corrects, je pensais juste que le fait de déplacer un élément vers un index inférieur ne fonctionnerait pas avec ce code - le this.Remove (item) décalerait les index. À tout le moins, vous insérez votre article une seule fois, au pire, vous essayez d'insérer après la fin de la liste. – Yoopergeek

1

Il se déclenche si un tri est appliqué à la source de liaison, si vous modifiez et si des données sont conservées dans le champ de tri, puis changez la position de l'enregistrement puis l'événement se déclenche.

1

Dans le même ordre à la réponse de Scott, vous pourriez faire quelque chose comme cette méthode d'extension:

//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; 
     } 
    } 
}

Cela ne produit pas les événements ItemMoved que vous après, mais évite d'avoir à sous-classe BindingList <>. Vous pouvez déclencher l'événement Reset (en utilisant ResetBindings()) une fois que vous avez fini de déplacer des éléments dans la liste. Peut être utile ...

Questions connexes