1.利用ListBox控件的两个事件:PreviewMouseMove、Drop
2.数据交换过程中的排序
#region 拖拽 public RelayCommand<MouseEventArgs> PreviewMouseMoveCommand => new RelayCommand<MouseEventArgs>(ExecutePreviewMouseMoveCommand); public RelayCommand<DragEventArgs> DropCommand => new RelayCommand<DragEventArgs>(ExecuteDropCommand); private void ExecutePreviewMouseMoveCommand(MouseEventArgs e) { ListBox_PreviewMouseMove(e); } private void ExecuteDropCommand(DragEventArgs e) { ListBox_Drop(e); } private Point _dragStartPoint; private T FindVisualParent<T>(DependencyObject child) where T : DependencyObject { var parentObject = VisualTreeHelper.GetParent(child); if (parentObject == null) return null; T parent = parentObject as T; if (parent != null) return parent; return FindVisualParent<T>(parentObject); } private void ListBox_PreviewMouseMove(MouseEventArgs e) { Point point = e.GetPosition(null); Vector diff = _dragStartPoint - point; if (e.LeftButton == MouseButtonState.Pressed && (Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance || Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance)) { //var lb = sender as ListBox; var lbi = FindVisualParent<ListBoxItem>(((DependencyObject)e.OriginalSource)); var lbi2 = FindVisualParent<ListBoxItem>(((DependencyObject)e.Source)); if (lbi != null) { DragDrop.DoDragDrop(lbi, lbi.DataContext, DragDropEffects.Move); } } } private void ListBox_Drop(DragEventArgs e) { var source = e.Data.GetData(typeof(MainModel)) as MainModel; //var target = e.OriginalSource; var lbi = FindVisualParent<ListBoxItem>(((DependencyObject)e.OriginalSource)); var target = lbi.DataContext as MainModel; int i = 0; //var listBox = sender as ListBox; //int sourceIndex = listBox.Items.IndexOf(source); //int targetIndex = listBox.Items.IndexOf(target); //Move(source, sourceIndex, targetIndex); int sourceIndex = Models.IndexOf(source); int targetIndex = Models.IndexOf(target); //Move(source, sourceIndex, targetIndex); Displace(source,target); } private void Move(MainModel source, int sourceIndex, int targetIndex) { if (sourceIndex < targetIndex) { _models.Insert(targetIndex + 1, source); _models.RemoveAt(sourceIndex); } else { int removeIndex = sourceIndex + 1; if (_models.Count + 1 > removeIndex) { _models.Insert(targetIndex, source); _models.RemoveAt(removeIndex); } } } private void Displace(MainModel source, MainModel target) { int sourceIndex = Models.IndexOf(source); int targetIndex = Models.IndexOf(target); var s = source.Clone; var t = target.Clone; //Models.Move(sourceIndex,targetIndex); Models.Displace0(sourceIndex,targetIndex); } #endregion
3.置换数据扩展方法
/// <summary> /// 置换数据 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="list"></param> /// <param name="oldIndex">原数据索引</param> /// <param name="newIndex">新数据索引</param> /// <returns></returns> public static bool Displace<T>(this ObservableCollection<T> list, int oldIndex, int newIndex) { if (oldIndex >= list.Count || newIndex >= list.Count || oldIndex < 0 || newIndex < 0 || oldIndex == newIndex) { return false; } try { var sel = list[oldIndex]; list[oldIndex] = list[newIndex]; list[newIndex] = sel; return true; } catch (Exception) { return false; } }