2009-08-06 19 views
11

Mam BindingList (T), który wyświetlany jest w DataGrid. Oglądam zdarzenia ListChanged i wykonuję różne akcje po wywołaniu zdarzenia ListChanged.Co powoduje wydarzenie ListChangedType.ItemMoved ListChange w bibliotece BindingList <T>?

Sprawdzam argument ListChangeType zdarzenia, aby sprawdzić, w jaki sposób lista została zmieniona, a następnie odpowiednio zareagować. Zauważyłem jednak, że istnieje typ zdarzenia ListChangedItemMoved.

Mam przyciski "Przenieś w górę" i "Przenieś w dół", aby przenieść elementy w górę iw dół listy. Ale to faktycznie usuwa wybrany element, a następnie umieszcza go na wyższej lub niższej pozycji.

Jednak nie widzę żadnej metody z BindingList (T), która wygląda tak, jakby przenieść element na liście. Czy też coś mi brakuje lub czy po prostu nie ma możliwości przeniesienia elementu do listy BindingList, która wywołałaby również zdarzenie ListChanged typu 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 
    } 
} 

Odpowiedz

9

Niestety, nic w BindingList podniesie ListChanged wydarzenie ListChangedType ustawiony ListChangedType.ItemMoved. BindingList dziedziczy z kolekcji, która nie zapewnia żadnego wsparcia dla "przenoszenia" pozycji na liście. BindingList nie dodaje żadnej obsługi tego typu zachowania.

Jeśli naprawdę potrzebujesz/chcesz odpowiedzieć na zdarzenia ListChangedType.ItemMoved, najlepszym rozwiązaniem jest wyprowadzenie własnej klasy z BindingList i zapewnienie własnych metod przenoszenia. Wewnątrz tych metod należy tymczasowo zawiesić wywoływanie zdarzeń ListChanged, wykonać ruch, usuwając/dodając, samodzielnie podnieść zdarzenie ListChanged za pomocą odpowiedniego ItemMoved ListChangedType, a następnie przywrócić wstrzymanie podnoszenia zdarzeń ListChanged.

To będzie wyglądać następująco *:

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

* kod Całkowicie niesprawdzone, ale powinien zilustrować główne punkty.

+4

Główne punkty wyglądają poprawnie, po prostu myślę, że powinienem wskazać, że przeniesienie elementu do niższego indeksu nie zadziała z tym kodem - to.Rozpocznij (element) spowoduje przesunięcie indeksów. Przynajmniej wstawiasz przedmiot jednorazowo, w najgorszym wypadku próbujesz wstawić za koniec listy. – Yoopergeek

1

Wyzwala, jeśli źródło powiązania ma zastosowany do niego rodzaj sortowania, jeśli zmienisz i dane przechowywane w polu sortowania, a następnie zmienią położenie rekordu, to zdarzenie zostanie wywołane.

1

w podobny sposób, aby odpowiedzieć Scotta, można zrobić coś takiego metodę rozszerzenia:

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

nie produkują wydarzenia ItemMoved Ci szukali ale oszczędza konieczności podklasy BindingList <>. Możesz wznowić zdarzenie Reset (za pomocą funkcji ResetBindings()) po zakończeniu przenoszenia elementów na liście. Może być pomocny ...