13

DataGridに表示しているBindingList(T)があります。ListChangedイベントを監視しており、 ListChangedイベントが呼び出されたときにさまざまなアクションを実行しています。

イベントのListChangeType引数をチェックして、リストがどのように変更されたかをチェックし、それに応じて応答しています。ただし、ListChangedイベントタイプItemMovedがあることに気付きました。

アイテムをリストの上下に移動するための「上に移動」と「下に移動」のボタンがあります。しかし、これらは実際には選択されたアイテムを削除し、それをより高い位置またはより低い位置に再挿入しています。

ただし、リスト内のアイテムを移動するように見えるBindingList(T)のメソッドは表示されません。それで、私は何かが足りないのですか、それともItemMovedタイプのListChangedイベントを引き起こすBindingList内のアイテムを移動する方法がありませんか?

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

3 に答える 3

11

残念ながら、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;
      }
   }
}

*完全にテストされていないコードですが、要点を説明する必要があります。

于 2009-08-17T04:02:41.877 に答える
1

バインディングソースに並べ替えが適用されている場合にトリガーされます。並べ替えフィールドに保持されているデータを変更してからレコードの位置を変更すると、イベントがトリガーされます。

于 2010-02-08T18:31:42.580 に答える
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()を使用して)Resetイベントを発生させることができます。役に立つかもしれません...

于 2010-11-25T03:14:14.647 に答える