是什么导致 BindingList中发生 ListChangedType.ItemMoved ListChange 事件?

发布于 2024-07-30 11:07:50 字数 1030 浏览 13 评论 0原文

我有一个在 DataGrid 中显示的 BindingList(T)。 我正在监视 ListChanged 事件,并在引发 ListChanged 事件时执行不同的操作。

我正在检查事件的 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
    }
}

I have a BindingList(T) that I am displaying in a DataGrid. I'm watching for ListChanged events and performing different actions when the ListChanged event is evoked.

I'm checking the ListChangeType argument of the event to check how the list was changed, and then responding accordingly. However, I noticed that there is a ListChanged event type ItemMoved.

I have buttons for "Move Up" and "Move Down" to move items up and down the list. But these are actually removing the selected item, and then reinserting it at a higher or lower position.

However, I don't see any method of BindingList(T) that looks like it would move an item in the list. So am I missing something or is there just no way to move an item in a BindingList that would also evoke a ItemMoved type ListChanged event?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

记忆消瘦 2024-08-06 11:07:50

不幸的是,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;
      }
   }
}

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

Unfortunately, nothing in BindingList will raise a ListChanged event with ListChangedType set to ListChangedType.ItemMoved. BindingList inherits from Collection which does not provide any kind of support for "moving" items in the list. BindingList does not add any support for this type of behavior either.

If you really need/want to respond the ListChangedType.ItemMoved events your best option is to derive your own class from BindingList and provide your own Move methods. Inside those methods you need to temporarily suspend raising ListChanged events, perform the move by removing/adding, raise the ListChanged event yourself with the appropriate ItemMoved ListChangedType, and then revert the suspension of raising ListChanged events.

It would look something like this*:

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

*Totally untested code, but it should illustrate the main points.

独孤求败 2024-08-06 11:07:50

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

It triggers if the binding source has a sort applied to it, if you change and data that is held in the sort field and it then changes the position of the record then the event triggers.

合久必婚 2024-08-06 11:07:50

与 Scott 的答案类似,您可以执行类似此扩展方法的操作:

//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<>。 完成移动列表中的项目后,您可以引发 Reset 事件(使用 ResetBindings())。 可能会有所帮助...

Along similar lines to Scott's answer, you could do something like this extension method:

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

This doesn't produce the ItemMoved events you were after but saves having to subclass BindingList<>. You can raise the Reset event (using ResetBindings()) once you've finished moving items in the list. Might be helpful...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文