2009-08-06 21 views
11

Tôi có một BindingList (T) mà tôi đang hiển thị trong một DataGrid. Tôi đang xem các sự kiện ListChanged và thực hiện các hành động khác nhau khi sự kiện ListChanged được gợi lên.Điều gì gây ra một sự kiện ListChangedType.ItemMoved ListChange trong một BindingList <T>?

Tôi đang kiểm tra đối số ListChangeType của sự kiện để kiểm tra xem danh sách đã được thay đổi như thế nào và sau đó trả lời tương ứng. Tuy nhiên, tôi nhận thấy rằng có ListChanged loại sự kiện ItemMoved.

Tôi có các nút để "Di chuyển lên" và "Di chuyển xuống" để di chuyển các mục lên và xuống danh sách. Nhưng đây thực sự là loại bỏ các mục đã chọn, và sau đó reinserting nó ở một vị trí cao hơn hoặc thấp hơn.

Tuy nhiên, tôi không thấy bất kỳ phương thức nào của BindingList (T) có vẻ như sẽ di chuyển một mục trong danh sách. Vì vậy, tôi thiếu một cái gì đó hoặc là không có cách nào chỉ để di chuyển một mục trong một BindingList mà cũng sẽ gợi lên một sự kiện ListChang loại 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 
    } 
} 

Trả lời

9

Thật không may, không có gì trong BindingList sẽ tăng sự kiện ListChanged với ListChangedType được đặt thành ListChangedType.ItemMoved. BindingList kế thừa từ Bộ sưu tập không cung cấp bất kỳ loại hỗ trợ nào cho các mục "di chuyển" trong danh sách. BindingList cũng không thêm bất kỳ hỗ trợ nào cho kiểu hành vi này.

Nếu bạn thực sự cần/muốn trả lời các sự kiện ListChangedType.ItemMoved, tùy chọn tốt nhất của bạn là lấy được lớp của riêng bạn từ BindingList và cung cấp các phương thức Move của riêng bạn. Bên trong những phương thức bạn cần tạm thời đình chỉ các sự kiện ListChanged nâng cao, thực hiện di chuyển bằng cách loại bỏ/thêm, nâng cao sự kiện ListChanged mình với ItemChoved ListChangedType thích hợp, và sau đó hoàn nguyên việc tạm ngưng các sự kiện ListChanged.

Nó sẽ giống như thế này *:

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

* Mã Hoàn toàn chưa được kiểm tra, nhưng nó phải minh họa những điểm chính.

+4

Các điểm chính trông chính xác, chỉ nghĩ rằng tôi nên chỉ ra rằng việc di chuyển một mục đến chỉ mục thấp hơn sẽ không hoạt động với mã này - this.Remove (mục) sẽ thay đổi các chỉ mục. Ít nhất bạn chèn một mục của bạn một lần, lúc tồi tệ nhất, bạn cố gắng chèn vào cuối danh sách. – Yoopergeek

1

Nó kích hoạt nếu nguồn ràng buộc có một loại áp dụng cho nó, nếu bạn thay đổi và dữ liệu được giữ trong trường sắp xếp và sau đó thay đổi vị trí của bản ghi rồi trình kích hoạt sự kiện.

1

Cùng dòng tương tự như câu trả lời của Scott, bạn có thể làm một cái gì đó giống như phương pháp mở rộng này:

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

này không tạo ra các sự kiện ItemMoved bạn đang theo đuổi nhưng tiết kiệm cần phải phân lớp BindingList <>. Bạn có thể nâng cao sự kiện Reset (sử dụng ResetBindings()) khi bạn đã hoàn thành việc di chuyển các mục trong danh sách. Có thể hữu ích ...

Các vấn đề liên quan