Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What causes a ListChangedType.ItemMoved ListChange Event in a BindingList<T>?

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
    }
}
like image 401
Eric Anastas Avatar asked Aug 06 '09 04:08

Eric Anastas


1 Answers

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.

like image 101
Scott Dorman Avatar answered Oct 02 '22 16:10

Scott Dorman