Browse Source

页面编辑-补充拖拽排序和拖拽排序Undo,redo

ZhouJieSheng 2 years ago
parent
commit
ddb390262f

+ 148 - 1
PDF Office/ViewModels/PageEdit/PageEditContentViewModel.cs

@@ -895,6 +895,26 @@ namespace PDF_Office.ViewModels.PageEdit
                     redoHistory = history;
                     break;
                 case ActionType.DragSort:
+                    //将字典倒序后,将每个Source的值恢复到Key的位置
+                    var SourceTargets = history.SourceTargetValue;
+                    var keys = SourceTargets.Keys.ToArray();
+                    Array.Reverse(keys);
+                    foreach(var key in keys)
+                    {
+                        MoveItemToIndex(SourceTargets[key], key);
+                    }
+                    //刷新页码等
+                    ReloadAfterOption(true,true,new Tuple<int, int>(0,PDFViewer.Document.PageCount));
+
+                    List<int> selectedPages = new List<int>();
+                    //将索引集合转换成页码集合
+                    foreach(var key in SourceTargets.Keys)
+                    {
+                        selectedPages.Add(key+1);
+                    }
+                    //通知UI选中Item
+                    NotifyUIToRefresh(selectedPages);
+                    redoHistory = history;
                     break;
                 default:
                     break;
@@ -927,7 +947,6 @@ namespace PDF_Office.ViewModels.PageEdit
                 case ActionType.LeftRotate:
                     var leftlist = history.SourceTargetValue.Keys.ToList<int>();
                     RotateSelectedPages(true, leftlist,true);
-
                     undoHistory.SourceTargetValue = history.SourceTargetValue;
                     undoHistory.Type = ActionType.RightRotate;
                     break;
@@ -942,6 +961,8 @@ namespace PDF_Office.ViewModels.PageEdit
                     undoHistory = history;
                     break;
                 case ActionType.DragSort:
+                    DragToSort(history.InsertIndex,history.SourceTargetValue.Keys.ToList<int>(),true);
+                    undoHistory = history;
                     break;
                 default:
                     break;
@@ -1751,6 +1772,132 @@ namespace PDF_Office.ViewModels.PageEdit
             }
         }
 
+        /// <summary>
+        /// 拖拽排序功能
+        /// </summary>
+        /// <param name="targetIndex"></param>
+        /// <param name="pageIndexs"></param>
+        public void DragToSort(int targetIndex,List<int> pageIndexs,bool IsFromUndoRedo =false)
+        {
+            //拖拽排序后需要重新选中项的集合
+            List<int> selectedPages = new List<int>();
+
+            //记录原位置和目标位置的字典,用于Undo,Redo恢复
+            Dictionary<int, int> SourceTargetValue = new Dictionary<int, int>();
+
+            bool result = false;
+
+            //排序前,先对所有页码排序
+            pageIndexs.Sort();
+            //要考虑每一次交换都会导致局部页码发生改变
+            //每次整体往后移动时,先移动大页码;整体往前移动时,先移动小页码;往中间移动时,再按上述两种情况分别移动
+            if (targetIndex <= pageIndexs[0])
+            {
+                for (int i = 0; i < pageIndexs.Count; i++)
+                {
+                    // list.Add(PageEditListBox.Items[pageIndexs[i]] as ListBoxItem);
+                    //sourceindex.Add(pageIndexs[i]);
+                    result = MoveItemToIndex(pageIndexs[i], targetIndex + i);
+                    if(!result)
+                    {
+                        return;
+                    }
+                    SourceTargetValue.Add(pageIndexs[i], targetIndex + i);
+                    selectedPages.Add(targetIndex + i+1);
+                }
+            }
+            else if (targetIndex > pageIndexs[pageIndexs.Count - 1])
+            {
+                //目标位置在所有选中内容右边 整体后移
+                for (int i = 0; i < pageIndexs.Count; i++)
+                {
+                    result = MoveItemToIndex(pageIndexs[pageIndexs.Count - 1 - i], targetIndex - 1 - i);
+                    if (!result)
+                    {
+                        return;
+                    }
+                    SourceTargetValue.Add(pageIndexs[pageIndexs.Count - 1 - i], targetIndex - 1 - i);
+                    selectedPages.Add(targetIndex - i);
+                }
+            }
+            else//目标位置在所有选中项中间
+            {
+                int i, j, k;
+                //找出PageEditListBox.Items中页码等于destpage的下标
+                for (k = 0; k < pageIndexs.Count - 1; k++)
+                {
+                    //这里要算入K---即前面部分的页面个数
+                    if (pageIndexs[k] < targetIndex && pageIndexs[k + 1] >= targetIndex)
+                    {
+                        break;
+                    }
+                }
+
+                //局部往后移动
+                for (i = 0; i <= k; i++)
+                {
+                    result = MoveItemToIndex(pageIndexs[k - i], targetIndex - 1 - i);
+                    if (!result)
+                    {
+                        return;
+                    }
+                    SourceTargetValue.Add(pageIndexs[k - i], targetIndex - 1 - i);
+                    selectedPages.Add(targetIndex - i);
+                }
+                int newIndex = targetIndex;
+                //局部往前移动
+                for (j = i; j < pageIndexs.Count; j++)
+                {
+                    result = MoveItemToIndex(pageIndexs[j], newIndex);
+                    if (!result)
+                    {
+                        return;
+                    }
+                    SourceTargetValue.Add(pageIndexs[j], newIndex);
+                    selectedPages.Add(newIndex + 1);
+                    newIndex++;
+                }
+            }
+            //通知UI选中Items
+            NotifyUIToRefresh(selectedPages);
+            //刷新页码和图片
+            ReloadAfterOption(true,true,new Tuple<int, int>(0,PDFViewer.Document.PageCount));
+
+            if (!IsFromUndoRedo)
+            {
+                //存入Undo栈
+                PageEditHistory history = new PageEditHistory();
+                history.Type = ActionType.DragSort;
+                history.SourceTargetValue = SourceTargetValue;
+                //用于Redo恢复
+                history.InsertIndex = targetIndex;
+                AddToUndoStack(history);
+            }
+        }
+
+        /// <summary>
+        /// 移动某个Item到指定位置
+        /// </summary>
+        private bool MoveItemToIndex(int sourceindex, int targetindex)
+        {
+            if (targetindex == sourceindex || targetindex < 0)
+            {
+                return false;
+            }
+            //文档层移动
+            var result = PDFViewer.Document.MovePage(sourceindex, targetindex);
+            if (!result)
+            {
+                return false;
+            }
+
+            //UI层移动
+            var source = PageEditItems[sourceindex];
+            PageEditItems.RemoveAt(sourceindex);
+            PageEditItems.Insert(targetindex, source);
+            return true;
+        }
+
         /// <summary>
         /// 从底层库获取对应页面的图片
         /// </summary>

+ 35 - 85
PDF Office/Views/PageEdit/PageEditContent.xaml.cs

@@ -546,19 +546,19 @@ namespace PDF_Office.Views.PageEdit
 
             var pos = e.GetPosition(ListPageEdit);
             var result = VisualTreeHelper.HitTest(ListPageEdit, pos);
-            if (result == null)
-            {
-                //超出当前可控区域
-                ExitDraging();
-                return;
-            }
-            //查找元数据
-            var sourcePerson = e.Data.GetData(typeof(StackPanel)) as StackPanel;
-            if (sourcePerson == null)
-            {
-                ExitDraging();
-                return;
-            }
+            //if (result == null)
+            //{
+            //    //超出当前可控区域
+            //    ExitDraging();
+            //    return;
+            //}
+            ////查找元数据
+            //var sourcePerson = e.Data.GetData(typeof(StackPanel)) as StackPanel;
+            //if (sourcePerson == null)
+            //{
+            //    ExitDraging();
+            //    return;
+            //}
             //查找目标数据
             int targetindex = 0;//目标插入位置
             if (InsertIndex != -1)
@@ -566,26 +566,26 @@ namespace PDF_Office.Views.PageEdit
                 //往前移动时  此index  不是准确的,需要处理++
                 targetindex = InsertIndex;
             }
-            else//基本不会命中  仅作为保险措施
-            {
-                var listBoxItem = CommonHelper.FindVisualParent<ListBoxItem>(result.VisualHit);
-                if (listBoxItem == null)
-                {
-                    ////鼠标停留在两个item之间或其他无效区域  暂时不做处理(比较麻烦)
-                    ExitDraging();
-                    return;
-                }
-                var targetPerson = listBoxItem;
-                targetPerson.Opacity = 1;
-                sourcePerson.Opacity = 1;
-                if (ReferenceEquals(targetPerson, sourcePerson))
-                {
-                    ExitDraging();
-                    return;
-                }
+            //else//基本不会命中  仅作为保险措施
+            //{
+            //    var listBoxItem = CommonHelper.FindVisualParent<ListBoxItem>(result.VisualHit);
+            //    if (listBoxItem == null)
+            //    {
+            //        ////鼠标停留在两个item之间或其他无效区域  暂时不做处理(比较麻烦)
+            //        ExitDraging();
+            //        return;
+            //    }
+            //    var targetPerson = listBoxItem;
+            //    targetPerson.Opacity = 1;
+            //    sourcePerson.Opacity = 1;
+            //    if (ReferenceEquals(targetPerson, sourcePerson))
+            //    {
+            //        ExitDraging();
+            //        return;
+            //    }
 
-                targetindex = ListPageEdit.Items.IndexOf(targetPerson);
-            }
+            //    targetindex = ListPageEdit.Items.IndexOf(targetPerson);
+            //}
 
             List<ListBoxItem> list = new List<ListBoxItem>();
             List<int> sourceindex = new List<int>();//需要保存每个页面对应的位置
@@ -594,67 +594,17 @@ namespace PDF_Office.Views.PageEdit
             //要先对所有选中项 根据页码排序
             for (int i = 0; i < ListPageEdit.SelectedItems.Count; i++)
             {
-                var pageindex = ListPageEdit.Items.IndexOf(ListPageEdit.SelectedItems[i] as ListBoxItem);
+                var pageindex = ListPageEdit.Items.IndexOf(ListPageEdit.SelectedItems[i] as PageEditItem);
                 pages.Add(pageindex);//存入的为页码索引值
             }
-            pages.Sort();
             if (pages.Count <= 0)
             {
                 ExitDraging();
                 return;
             }
 
-            //要考虑每一次交换都会导致局部页码发生改变
-            //每次整体往后移动时,先移动大页码;整体往前移动时,先移动小页码;往中间移动时,再按上述两种情况分别移动
-            //if (targetindex <= pages[0])// 目标位置在所有选中内容左边,整体前移动  优先先判断左移的情况
-            //{
-            //    sourceindex.Add(-1);
-            //    list = new List<ListBoxItem>();
-            //    for (int i = 0; i < pages.Count; i++)
-            //    {
-            //        list.Add(PageEditListBox.Items[pages[i]] as ListBoxItem);
-            //        sourceindex.Add(pages[i]);
-            //        DragToSort(pages[i], targetindex + i);
-            //    }
-            //}
-            //else if (targetindex > pages[pages.Count - 1])//目标位置在所有选中内容右边 整体后移
-            //{
-            //    sourceindex.Add(1);
-            //    list = new List<ListBoxItem>();
-            //    for (int i = 0; i < pages.Count; i++)
-            //    {
-            //        list.Add(PageEditListBox.Items[pages[pages.Count - 1 - i]] as ListBoxItem);
-            //        sourceindex.Add(pages[pages.Count - 1 - i]);
-            //        DragToSort(pages[pages.Count - 1 - i], targetindex - 1 - i/* + (PageEditListBox.SelectedItems.Count - 1 - i)*/);
-            //    }
-            //}
-            //else//目标位置在所有选中项中间
-            //{
-            //    int i, j, k;
-            //    for (k = 0; k < pages.Count - 1; k++)//找出PageEditListBox.Items中页码等于destpage的下标
-            //    {
-            //        //这里要算入K---即前面部分的页面个数
-            //        if (pages[k] < targetindex && pages[k + 1] >= targetindex)
-            //            break;
-            //    }
-
-            //    sourceindex.Add(0);
-            //    list = new List<ListBoxItem>();
-            //    for (i = 0; i <= k; i++)//局部往后移动
-            //    {
-            //        list.Add(PageEditListBox.Items[pages[k - i]] as ListBoxItem);
-            //        sourceindex.Add(pages[k - i]);
-            //        DragToSort(pages[k - i], targetindex - 1 - i);
-            //    }
-            //    for (j = i; j < pages.Count; j++)//局部往前移动
-            //    {
-            //        list.Add(PageEditListBox.Items[pages[j]] as ListBoxItem);
-            //        sourceindex.Add(pages[j]);
-            //        DragToSort(pages[j], targetindex);
-            //        targetindex++;
-            //    }
-            //    sourceindex.Add(k);//往中间移时, index数组的最后一位 表示 间隔位置K
-            //}
+            viewModel.DragToSort(targetindex,pages);
+            ExitDraging();
             isDraging = false;
         }