2009-08-06 81 views
11

我有一个绑定列表(T),我显示在DataGrid。我正在观看ListChanged事件并执行不同的操作时,会触发ListChanged事件。在BindingList中导致ListChangedType.ItemMoved ListChange事件的原因<T>?

我在检查ListChangeType事件的参数,以检查列表如何更改,然后相应地作出响应。但是,我注意到有一个ListChanged事件类型ItemMoved

我有“上移”和“下移”的按钮来上下移动项目。但这些实际上是删除选定的项目,然后将它重新插入到更高或更低的位置。

但是,我没有看到任何方法BindingList(T)看起来像它会移动列表中的项目。所以我错过了什么,或者是没有办法移动一个BindingList中的项目,这也会引发一个ItemMoved类型的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 
    } 
} 

回答

9

不幸的是,没有什么的BindingList将提高与ListChangedType设置为ListChangedType.ItemMoved一个ListChanged事件。 BindingList继承自Collection,它不为列表中的“移动”项目提供任何支持。 BindingList不会为这种类型的行为添加任何支持。

如果您确实需要/想要响应ListChangedType.ItemMoved事件,您最好的选择是从BindingList派生自己的类并提供您自己的Move方法。在这些方法中,您需要临时暂停引发ListChanged事件,通过删除/添加来执行移动,使用适当的ItemMoved ListChangedType自己引发ListChanged事件,然后恢复引发ListChanged事件的暂停。

这将是这个样子*:

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

*完全未经测试的代码,但它应该说明的要点。

+4

要点看起来正确,只是想我应该指出,将一个项目移动到较低的索引将无法使用此代码 - this.Remove(item)将会移动索引。至少你一次插入你的项目,最坏的情况是,你试图插入到列表的最后。 – Yoopergeek 2009-10-30 19:46:57

1

它会触发绑定源是否应用了排序,如果您更改了排序字段中保存的数据,然后它会更改记录的位置,然后触发该事件。

1

按照类似的思路斯科特的答案,你可以做这样的事情扩展方法:

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

这不会产生你以后ItemMoved事件,但省去了子类的BindingList <>。一旦完成移动列表中的项目,您可以引发重置事件(使用ResetBindings())。可能有帮助...

相关问题