先上效果图:

拖动改变ListView行数据顺序

关键代码:

  1 public partial class Window1 : System.Windows.Window
  2     {
  3         ListViewDragDropManager<Task> dragMgr;
  4         ListViewDragDropManager<Task> dragMgr2;
  5 
  6         public Window1()
  7         {
  8             InitializeComponent();
  9             this.Loaded += Window1_Loaded;
 10         }
 11 
 12         #region Window1_Loaded
 13 
 14         void Window1_Loaded( object sender, RoutedEventArgs e )
 15         {
 16             // Give the ListView an ObservableCollection of Task 
 17             // as a data source.  Note, the ListViewDragManager MUST
 18             // be bound to an ObservableCollection, where the collection's
 19             // type parameter matches the ListViewDragManager's type
 20             // parameter (in this case, both have a type parameter of Task).
 21             ObservableCollection<Task> tasks = Task.CreateTasks();
 22             this.listView.ItemsSource = tasks;
 23 
 24             this.listView2.ItemsSource = new ObservableCollection<Task>();
 25 
 26             // This is all that you need to do, in order to use the ListViewDragManager.
 27             this.dragMgr = new ListViewDragDropManager<Task>( this.listView );
 28             this.dragMgr2 = new ListViewDragDropManager<Task>( this.listView2 );
 29 
 30             // Turn the ListViewDragManager on and off. 
 31             this.chkManageDragging.Checked += delegate { this.dragMgr.ListView = this.listView; };
 32             this.chkManageDragging.Unchecked += delegate { this.dragMgr.ListView = null; };
 33 
 34             // Show and hide the drag adorner.
 35             this.chkDragAdorner.Checked += delegate { this.dragMgr.ShowDragAdorner = true; };
 36             this.chkDragAdorner.Unchecked += delegate { this.dragMgr.ShowDragAdorner = false; };
 37 
 38             // Change the opacity of the drag adorner.
 39             this.sldDragOpacity.ValueChanged += delegate { this.dragMgr.DragAdornerOpacity = this.sldDragOpacity.Value; };
 40 
 41             // Apply or remove the item container style, which responds to changes
 42             // in the attached properties of ListViewItemDragState.
 43             this.chkApplyContStyle.Checked += delegate { this.listView.ItemContainerStyle = this.FindResource( "ItemContStyle" ) as Style; };
 44             this.chkApplyContStyle.Unchecked += delegate { this.listView.ItemContainerStyle = null; };
 45 
 46             // Use or do not use custom drop logic.
 47             this.chkSwapDroppedItem.Checked += delegate { this.dragMgr.ProcessDrop += dragMgr_ProcessDrop; };
 48             this.chkSwapDroppedItem.Unchecked += delegate { this.dragMgr.ProcessDrop -= dragMgr_ProcessDrop; };
 49 
 50             // Show or hide the lower ListView.
 51             this.chkShowOtherListView.Checked += delegate { this.listView2.Visibility = Visibility.Visible; };
 52             this.chkShowOtherListView.Unchecked += delegate { this.listView2.Visibility = Visibility.Collapsed; };
 53 
 54             // Hook up events on both ListViews to that we can drag-drop
 55             // items between them.
 56             this.listView.DragEnter += OnListViewDragEnter;
 57             this.listView2.DragEnter += OnListViewDragEnter;
 58             this.listView.Drop += OnListViewDrop;
 59             this.listView2.Drop += OnListViewDrop;
 60         }
 61 
 62         #endregion // Window1_Loaded
 63 
 64         #region dragMgr_ProcessDrop
 65 
 66         // Performs custom drop logic for the top ListView.
 67         void dragMgr_ProcessDrop( object sender, ProcessDropEventArgs<Task> e )
 68         {
 69             // This shows how to customize the behavior of a drop.
 70             // Here we perform a swap, instead of just moving the dropped item.
 71 
 72             int higherIdx = Math.Max( e.OldIndex, e.NewIndex );
 73             int lowerIdx = Math.Min( e.OldIndex, e.NewIndex );
 74 
 75             if( lowerIdx < 0 )
 76             {
 77                 // The item came from the lower ListView
 78                 // so just insert it.
 79                 e.ItemsSource.Insert( higherIdx, e.DataItem );
 80             }
 81             else
 82             {
 83                 // null values will cause an error when calling Move.
 84                 // It looks like a bug in ObservableCollection to me.
 85                 if( e.ItemsSource[lowerIdx] == null ||
 86                     e.ItemsSource[higherIdx] == null )
 87                     return;
 88 
 89                 // The item came from the ListView into which
 90                 // it was dropped, so swap it with the item
 91                 // at the target index.
 92                 e.ItemsSource.Move( lowerIdx, higherIdx );
 93                 e.ItemsSource.Move( higherIdx - 1, lowerIdx );
 94             }
 95 
 96             // Set this to 'Move' so that the OnListViewDrop knows to 
 97             // remove the item from the other ListView.
 98             e.Effects = DragDropEffects.Move;
 99         }
100 
101         #endregion // dragMgr_ProcessDrop
102 
103         #region OnListViewDragEnter
104 
105         // Handles the DragEnter event for both ListViews.
106         void OnListViewDragEnter( object sender, DragEventArgs e )
107         {
108             e.Effects = DragDropEffects.Move;
109         }
110 
111         #endregion // OnListViewDragEnter
112 
113         #region OnListViewDrop
114 
115         // Handles the Drop event for both ListViews.
116         void OnListViewDrop( object sender, DragEventArgs e )
117         {
118             if( e.Effects == DragDropEffects.None )
119                 return;
120 
121             Task task = e.Data.GetData( typeof( Task ) ) as Task;
122             if( sender == this.listView )
123             {
124                 if( this.dragMgr.IsDragInProgress )
125                     return;
126 
127                 // An item was dragged from the bottom ListView into the top ListView
128                 // so remove that item from the bottom ListView.
129                 (this.listView2.ItemsSource as ObservableCollection<Task>).Remove( task );
130             }
131             else
132             {
133                 if( this.dragMgr2.IsDragInProgress )
134                     return;
135 
136                 // An item was dragged from the top ListView into the bottom ListView
137                 // so remove that item from the top ListView.
138                 (this.listView.ItemsSource as ObservableCollection<Task>).Remove( task );
139             }
140         }
141 
142         #endregion // OnListViewDrop
143 
144     }
Window1.xaml.cs

相关文章: