Ver código fonte

页面编辑-补充页面编辑拖拽逻辑

ZhouJieSheng 2 anos atrás
pai
commit
6f34943c4e

+ 2 - 1
PDF Office/Styles/WindowsStyle.xaml

@@ -8,9 +8,10 @@
                 <WindowChrome
                     CaptionHeight="32"
                     CornerRadius="10"
-                    GlassFrameThickness="0"
+                    GlassFrameThickness="-1"
                     ResizeBorderThickness="5"
                     UseAeroCaptionButtons="False" />
+                <!--  GlassFrameThickness="-1" win11上显示异常  -->
             </Setter.Value>
         </Setter>
         <Setter Property="Template">

+ 14 - 5
PDF Office/Views/Dialog/PageEditDialogs/InsertDialog.xaml

@@ -24,19 +24,28 @@
                     <RowDefinition Height="auto" />
                     <RowDefinition Height="auto" />
                 </Grid.RowDefinitions>
-                <ListBox />
+                <ListBox BorderThickness="0" />
                 <StackPanel Grid.Row="1" Margin="16,0">
                     <TextBlock
                         FontSize="14"
                         FontWeight="SemiBold"
                         Text="页面大小" />
-                    <RadioButton Margin="0,12,0,0" Content="当前页" />
+                    <RadioButton
+                        Margin="0,12,0,0"
+                        Content="当前页"
+                        GroupName="PageSize" />
                     <StackPanel Margin="0,12" Orientation="Horizontal">
-                        <RadioButton VerticalAlignment="Center" Content="标准" />
+                        <RadioButton
+                            VerticalAlignment="Center"
+                            Content="标准"
+                            GroupName="PageSize" />
                         <ComboBox Margin="8,0" />
                     </StackPanel>
                     <StackPanel Margin="0,0,0,12" Orientation="Horizontal">
-                        <RadioButton VerticalAlignment="Center" Content="自定义" />
+                        <RadioButton
+                            VerticalAlignment="Center"
+                            Content="自定义"
+                            GroupName="PageSize" />
                         <TextBox
                             Width="80"
                             Height="32"
@@ -70,7 +79,7 @@
                     Height="32"
                     Margin="16,0"
                     HorizontalAlignment="Right"
-                    Command="{Binding CancelCommnad}"
+                    Command="{Binding CancelCommand}"
                     Content="取消" />
                 <Button
                     Width="98"

+ 41 - 18
PDF Office/Views/Dialog/PageEditDialogs/SplitDialog.xaml

@@ -23,27 +23,45 @@
                     <RowDefinition />
                     <RowDefinition />
                 </Grid.RowDefinitions>
-                <StackPanel Margin="16,0">
+                <StackPanel Margin="16,4,16,0">
                     <TextBlock
+                        Margin="0,12"
                         FontSize="14"
                         FontWeight="SemiBold"
                         Text="拆分方式" />
                     <StackPanel Orientation="Horizontal">
-                        <RadioButton Margin="0,12,0,0" Content="平均每" />
+                        <RadioButton
+                            Name="RbtnPage"
+                            Margin="0,12,0,0"
+                            Content="平均每"
+                            IsChecked="True" />
                         <TextBox
                             Width="110"
                             Height="32"
-                            Margin="8,0" />
+                            Margin="8,0"
+                            IsEnabled="{Binding ElementName=RbtnPage, Path=IsChecked}" />
                         <TextBlock VerticalAlignment="Center" Text="页拆分为一个PDF文件" />
                     </StackPanel>
                     <StackPanel Margin="0,12" Orientation="Horizontal">
-                        <RadioButton VerticalAlignment="Center" Content="平均拆分为" />
-                        <ComboBox Width="110" Margin="8,0" />
+                        <RadioButton
+                            Name="RbtnPdf"
+                            VerticalAlignment="Center"
+                            Content="平均拆分为" />
+                        <ComboBox
+                            Width="110"
+                            Margin="8,0"
+                            IsEnabled="{Binding ElementName=RbtnPdf, Path=IsChecked}" />
                         <TextBlock VerticalAlignment="Center" Text="个PDF文件" />
                     </StackPanel>
                     <StackPanel Margin="0,0,0,12" Orientation="Horizontal">
-                        <RadioButton VerticalAlignment="Center" Content="按页面范围拆分" />
-                        <ComboBox Width="110" Margin="8,0" />
+                        <RadioButton
+                            x:Name="RbtnPagerange"
+                            VerticalAlignment="Center"
+                            Content="按页面范围拆分" />
+                        <ComboBox
+                            Width="110"
+                            Margin="8,0"
+                            IsEnabled="{Binding ElementName=RbtnPagerange, Path=IsChecked}" />
                     </StackPanel>
                 </StackPanel>
                 <StackPanel Grid.Row="1" Margin="16,0">
@@ -54,34 +72,39 @@
                     <TextBox
                         Width="346"
                         Height="32"
-                        HorizontalAlignment="Left" />
-                    <CheckBox Margin="0,6" Content="将原始文档名前置" />
+                        HorizontalAlignment="Left"
+                        Focusable="False"
+                        IsReadOnly="True" />
+                    <CheckBox
+                        Margin="0,6"
+                        Content="将原始文档名前置"
+                        IsChecked="True" />
 
 
                     <StackPanel Orientation="Horizontal">
                         <CheckBox
+                            Name="ChkSign"
                             Width="{Binding ElementName=ChkSeparator, Path=ActualWidth}"
                             Margin="0,6"
-                            Content="标签" />
+                            Content="标签"
+                            IsChecked="True" />
                         <TextBox
                             Width="110"
                             Height="32"
-                            Margin="16,0" />
+                            Margin="16,0"
+                            IsEnabled="{Binding ElementName=ChkSign, Path=IsChecked}" />
                     </StackPanel>
                     <StackPanel Orientation="Horizontal">
                         <CheckBox
                             Name="ChkSeparator"
                             Margin="0,6"
-                            Content="分隔符" />
+                            Content="分隔符"
+                            IsChecked="True" />
                         <TextBox
                             Width="110"
                             Height="32"
-                            Margin="16,0" />
-                    </StackPanel>
-
-                    <StackPanel Orientation="Horizontal">
-                        <RadioButton Margin="0,12,0,16" Content="纵向页面" />
-                        <RadioButton Margin="24,12,0,16" Content="横向页面" />
+                            Margin="16,0"
+                            IsEnabled="{Binding ElementName=ChkSeparator, Path=IsChecked}" />
                     </StackPanel>
                 </StackPanel>
             </Grid>

+ 29 - 1
PDF Office/Views/PageEdit/PageEditContent.xaml

@@ -102,7 +102,7 @@
     </UserControl.Resources>
 
     <Border BorderBrush="#F2F2F2" BorderThickness="0,1,0,0">
-        <Grid>
+        <Grid DragOver="Grid_DragOver">
             <Grid.RowDefinitions>
                 <RowDefinition Height="40" />
                 <RowDefinition />
@@ -256,6 +256,7 @@
                 Padding="0"
                 AllowDrop="True"
                 Background="#E7E9EC"
+                Drop="ListPageEdit_Drop"
                 ItemTemplate="{StaticResource PageEditListBoxItemTemplate}"
                 ItemsSource="{Binding PageEditItems}"
                 PreviewMouseLeftButtonDown="ListPageEdit_PreviewMouseLeftButtonDown"
@@ -298,6 +299,33 @@
                 Opacity="0.3"
                 Stroke="#AACCEE"
                 StrokeThickness="2" />
+            <!--  插入标记  -->
+            <Line
+                Name="LineInset"
+                Grid.Row="1"
+                AllowDrop="True"
+                Drop="MidLane_Drop"
+                Stroke="#FF477EDE"
+                StrokeEndLineCap="Triangle"
+                StrokeStartLineCap="Triangle"
+                StrokeThickness="5"
+                Visibility="Collapsed"
+                X1="20"
+                X2="20"
+                Y1="0"
+                Y2="150" />
+            <!--  拖拽虚影  -->
+            <Image
+                Name="ImgPicture"
+                Grid.Row="1"
+                HorizontalAlignment="Left"
+                VerticalAlignment="Top"
+                AllowDrop="True"
+                Drop="ImgPicture_Drop"
+                Opacity="0.8"
+                RenderOptions.BitmapScalingMode="HighQuality"
+                UseLayoutRounding="True"
+                Visibility="{Binding ElementName=LineInset, Path=Visibility}" />
             <cus:ToastControl
                 Grid.Row="1"
                 Width="auto"

+ 577 - 36
PDF Office/Views/PageEdit/PageEditContent.xaml.cs

@@ -63,6 +63,39 @@ namespace PDF_Office.Views.PageEdit
         /// </summary>
         private ScrollEventType scrolltype = ScrollEventType.EndScroll;
 
+        //鼠标点击时在item中的位置  实现类似点哪拖哪的细节
+        private double item_x;
+
+        private double item_y;
+
+        //插入标记代表的插入位置
+        private int InsertIndex = -1;
+
+        //拖动的Item
+        private ListBoxItem tempItem;
+
+        ///鼠标是否停留在item前半部
+        ///显示在前半部时,获取的index为实际索引值
+        ///显示在后半部时,获取的index需要+1
+        private bool isFrontHalf = false;
+
+        /// <summary>
+        /// 是否正在拖拽排序中,通过该变量避免单击触发拖动
+        /// </summary>
+        private bool isDraging = false;
+
+        //是否正在从外部拖入文件
+        private bool isDragingEnter = false;
+
+        /// <summary>
+        /// 是否需要自动滚动
+        /// </summary>
+
+        private bool needScroll = false;
+
+        //自动滚动速度
+        private int speed = 0;
+
         public PageEditContent()
         {
             InitializeComponent();
@@ -239,6 +272,7 @@ namespace PDF_Office.Views.PageEdit
             {
                 if (e.LeftButton == MouseButtonState.Pressed)
                 {
+                    //鼠标框选逻辑
                     if (startChoose)
                     {
                         var position = e.GetPosition(ListPageEdit);
@@ -246,55 +280,66 @@ namespace PDF_Office.Views.PageEdit
                         {
                             startChoose = false;
                             RectChoose.Visibility = Visibility.Collapsed;
-                            Mouse.Capture(null);//暂时未想到靠近顶部和底部自动翻滚的好方法,只能先屏蔽这部分功能
+                            //暂时未想到靠近顶部和底部自动翻滚的好方法,只能先屏蔽这部分功能
+                            Mouse.Capture(null);
                             return;
                         }
+                        //矩形框内的item设为选中
                         DoSelectItems();
                         return;
                     }
                     //拖拽排序的逻辑
-                    //var pos = e.GetPosition(ListPageEdit);
-                    //if (pos.Y < 0 || pos.Y > ListPageEdit.ActualHeight)
-                    //{
-                    //    MidLane.Visibility = Visibility.Collapsed;
-                    //    return;
-                    //}
-                    //HitTestResult result = VisualTreeHelper.HitTest(PageEditListBox, pos);
-                    //if (result == null)
-                    //{
-                    //    return;
-                    //}
-                    //var listBoxItem = CommonHelper.FindVisualParent<ListBoxItem>(result.VisualHit);
-                    //if (listBoxItem == null)
-                    //{
-                    //    return;
-                    //}
-                    //isDragingEnter = false;
-                    //tempItem = listBoxItem;
-                    //var panel = GetPanel(tempItem);
-
-                    //var item_pos = e.GetPosition(panel);
-                    //if (item_pos != null)
-                    //{
-                    //    item_x = item_pos.X;
-                    //    item_y = item_pos.Y;
-                    //}
-                    //var scroll = GetScrollHost(PageEditListBox);
-                    //DataObject dataObj = new DataObject(listBoxItem.Content as StackPanel);
-                    //DragDrop.DoDragDrop(PageEditListBox, dataObj, DragDropEffects.Move);
-                    //Mouse.Capture(PageEditListBox);
-                    //return;
+                    var pos = e.GetPosition(ListPageEdit);
+                    if (pos.Y < 0 || pos.Y > ListPageEdit.ActualHeight)
+                    {
+                        LineInset.Visibility = Visibility.Collapsed;
+                        return;
+                    }
+                    HitTestResult result = VisualTreeHelper.HitTest(ListPageEdit, pos);
+                    if (result == null)
+                    {
+                        return;
+                    }
+                    var listBoxItem = CommonHelper.FindVisualParent<ListBoxItem>(result.VisualHit);
+                    if (listBoxItem == null)
+                    {
+                        return;
+                    }
+                    isDragingEnter = false;
+                    tempItem = listBoxItem;
+
+                    var item_pos = e.GetPosition(tempItem);
+                    if (item_pos != null)
+                    {
+                        item_x = item_pos.X;
+                        item_y = item_pos.Y;
+                    }
+                    var scroll = GetScrollHost(ListPageEdit);
+
+                    //string tempPath = System.IO.Path.Combine(System.IO.Path.GetTempPath(), "Temp.pdf");
+                    //System.IO.File.Create(tempPath);
+                    //string[] files = new string[1];
+                    //files[0] = tempPath;
+                    DataObject dataObj = new DataObject(DataFormats.FileDrop);
+                    DragDrop.DoDragDrop(ListPageEdit, dataObj, DragDropEffects.Move);
+                    Mouse.Capture(ListPageEdit);
+                    return;
                 }
                 RectChoose.Visibility = Visibility.Collapsed;
                 startChoose = false;
                 Mouse.Capture(null);
             }
-            catch (Exception ex)
+            catch
             {
-               // MidLane.Visibility = Visibility.Collapsed;
+               LineInset.Visibility = Visibility.Collapsed;
             }
         }
 
+        /// <summary>
+        /// 判断是否开始框选、记录框选起始位置
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
         private void ListPageEdit_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
         {
             var pos = e.GetPosition(ListPageEdit);
@@ -315,13 +360,17 @@ namespace PDF_Office.Views.PageEdit
                 }
                 //点击空白处时开始框选
                 startChoose = true;
-                ListPageEdit.SelectedItems.Clear();
+                if (ListPageEdit.SelectedItems.Count > 0)
+                {
+                    ListPageEdit.SelectedItems.Clear();
+                }
                 starPosition = e.GetPosition(ListPageEdit);
                 starPosition = new Point(starPosition.X, starPosition.Y + GetWrapPanel(ListPageEdit).VerticalOffset);
                 Mouse.Capture(ListPageEdit);
                 return;
             }
-            startChoose = false;//选中了item 时,不能框选
+            //选中了item 时,不能框选
+            startChoose = false;
         }
 
         private void ListPageEdit_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
@@ -380,5 +429,497 @@ namespace PDF_Office.Views.PageEdit
             return;
         }
 
+        /// <summary>
+        /// 计算插入标记线和虚影显示
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void ListPageEdit_DragOver(object sender, DragEventArgs e)
+        {
+            try
+            {
+                //ctrl建按下 不显示插入标记和虚影  因为释放不会响应drop事件
+                if (e.KeyStates == (DragDropKeyStates.ControlKey | DragDropKeyStates.LeftMouseButton) || e.KeyStates == (DragDropKeyStates.ShiftKey | DragDropKeyStates.LeftMouseButton | DragDropKeyStates.ControlKey))
+                    return;
+
+                //滚动后有 位置不准确 要减去滚动偏移量
+                //控制线的位置
+                var pos = e.GetPosition(ListPageEdit);
+                var result = VisualTreeHelper.HitTest(ListPageEdit, pos);
+                if (result == null)
+                {
+                    //MidLane.Visibility = Visibility.Collapsed;
+                    //return;
+                }
+
+                //获取当前鼠标指针下的容器
+                var listBoxItem = CommonHelper.FindVisualParent<ListBoxItem>(result.VisualHit);
+                if (listBoxItem == null)
+                {
+                    //MidLane.Visibility = Visibility.Collapsed;
+                    //return;
+                }
+
+                #region  计算虚影位置
+                //xaml层 要设置 虚影控件为左上
+                double xPos = 0;
+                double yPos = 0;
+                //内部拖动
+                if (!isDragingEnter)
+                {
+                    //Viewbox viewBox = (tempItem.Content as StackPanel).Children[0] as Viewbox;//获取item宽度
+
+                    ImgPicture.Width = tempItem.ActualWidth;
+                    ImgPicture.Height = tempItem.ActualHeight;
+                    ImgPicture.Source = (tempItem.DataContext as PageEditItem).Image;
+                    xPos = e.GetPosition(ListPageEdit).X - item_x;
+                    yPos = e.GetPosition(ListPageEdit).Y - item_y;
+                }
+                //else
+                //{
+                //    //从外部拖入的逻辑
+                //    //var pic = ToBitmapSource(dragingEnterPath);
+                //    //ShadowPicture.Width = pic.Width;
+                //    //ShadowPicture.Height = pic.Height;
+                //    //ShadowPicture.Source = pic;
+                //    //xPos = e.GetPosition(ListPageEdit).X - pic.Width / 2;
+                //    //yPos = e.GetPosition(ListPageEdit).Y - pic.Height / 2;
+                //}
+
+                ImgPicture.Margin = new Thickness(xPos, yPos, 0, 0);
+                #endregion
+
+                #region 计算插入标记位置
+                var scroll = GetScrollHost(ListPageEdit);
+                if (listBoxItem != null)
+                {
+                    //虚拟化影响到该值计算
+                    var p = VisualTreeHelper.GetOffset(listBoxItem);//计算控件在容器中的偏移(位置)
+                    LineInset.Visibility = Visibility.Visible;
+
+                    var panel = GetWrapPanel(ListPageEdit);
+                    var item = (ListPageEdit.ItemContainerGenerator.ContainerFromIndex(0) as ListBoxItem).DesiredSize.Width;
+
+                    int count = (int)(panel.ViewportWidth / item);
+                    var gap = (panel.ViewportWidth - count * item) / (count + 1) * 1.0;
+
+                    LineInset.X2 = LineInset.X1 = p.X + gap / 2 + listBoxItem.DesiredSize.Width;
+
+                    if (pos.X < p.X + gap / 2 + listBoxItem.ActualWidth / 2)
+                    {
+                        isFrontHalf = true;//前半部 线条出现在位置前 
+                        LineInset.X2 = LineInset.X1 = p.X - gap / 2;
+                        InsertIndex = ListPageEdit.Items.IndexOf(listBoxItem);
+                    }
+                    else
+                    {
+                        isFrontHalf = false;
+                        InsertIndex = ListPageEdit.Items.IndexOf(listBoxItem) + 1;
+                    }
+                    //MidLane.Y1 = p.Y - scroll.VerticalOffset;//向下滑动后要减去滑动值
+                    LineInset.Y1 = p.Y;
+                    if (LineInset.Y1 < 0)//避免超出上边界
+                    {
+                        LineInset.Y1 = 0;
+                    }
+                    //MidLane.Y2 = p.Y + listBoxItem.ActualHeight - scroll.VerticalOffset;//仿智能滚动后可能会导致 垂直滚动偏量不准确
+                    LineInset.Y2 = p.Y + listBoxItem.ActualHeight;
+                    if (LineInset.Y2 < 0)
+                    {
+                        LineInset.Y2 = 0;
+                    }
+                }
+                #endregion
+
+                //暂时处理  鼠标移出边框时,虚影的显示问题
+                if (pos.Y <= 30 || pos.Y >= ListPageEdit.ActualHeight - 10)
+                {
+                    LineInset.Visibility = Visibility.Collapsed;
+                    needScroll = false;
+                }
+
+                if (pos.X <= 40 || pos.X >= scroll.ViewportWidth - 50)
+                {
+                    LineInset.Visibility = Visibility.Collapsed;
+                    needScroll = false;
+                }
+
+                #region 靠近上下边界时,自动滚动,离边界越近,滚动速度越快
+                //speed = 0;
+                //if (pos.Y >= PageEditListBox.ActualHeight - 30)
+                //{
+                //    speed = 30 - (int)(PageEditListBox.ActualHeight - pos.Y);
+                //    needScroll = true;
+                //}
+                //else if (pos.Y <= 30)
+                //{
+                //    speed = (int)(pos.Y - 30);
+                //    needScroll = true;
+                //}
+                //else
+                //    needScroll = false;
+
+                //var v = scroll.VerticalOffset;
+                //scroll.ScrollToVerticalOffset(v + speed);//触发连续滚动
+                #endregion
+            }
+            catch (Exception ex)
+            {
+
+            }
+        }
+
+        /// <summary>
+        /// 退出拖拽模式
+        /// </summary>
+        private void ExitDraging()
+        {
+            LineInset.Visibility = Visibility.Collapsed;
+            isDraging = false;
+        }
+
+        /// <summary>
+        /// 拖拽释放后的处理逻辑
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void ListPageEdit_Drop(object sender, DragEventArgs e)
+        {
+            needScroll = false;
+            if (!isDraging)
+            {
+                //未拖拽时隐藏插入标记和虚影
+                LineInset.Visibility = Visibility.Collapsed;
+                return;
+            }
+            #region 功能付费锁
+            //    //if (!App.IsActive())
+            //    //{
+            //    //    MidLane.Visibility = Visibility.Collapsed;
+            //    //    IAPFunctionDialog dialog = new IAPFunctionDialog("PageEdit");
+            //    //    dialog.ShowDialog();
+            //    //    return;
+            //    //}
+            #endregion
+
+            #region  从外部拖拽插入文件
+            //if (isDragingEnter)
+            //{
+
+
+            //    //在当前位置插入整个pdf
+            //    CPDFDocument dragDoc = CPDFDocument.InitWithFilePath(dragingEnterPath);
+            //    if (dragDoc.IsLocked)
+            //    {
+            //        VerifyPasswordDialog dialog = new VerifyPasswordDialog(dragDoc);
+            //        dialog.ShowDialog();
+            //        if (dragDoc.IsLocked)
+            //            return;
+            //    }
+            //    if (dragingEnterPath.Substring(dragingEnterPath.LastIndexOf(".")).ToLower() == ".pdf")
+            //    {
+            //        if (dragDoc != null)
+            //        {
+            //            int index = InsertIndex == -1 ? 0 : InsertIndex;
+            //            pdfViewer.Document.ImportPagesAtIndex(dragDoc, "1-" + dragDoc.PageCount, index);
+            //            PopulateThumbnailList();
+            //            ItemsInViewHitTest();
+
+            //            pdfViewer.UndoManager.ClearHistory();
+            //            pdfViewer.UndoManager.CanSave = true;
+            //            pdfViewer.ReloadDocument();
+            //            PageEditListBox.ScrollIntoView(PageEditListBox.SelectedItem as ListBoxItem);
+            //            PageMoved.Invoke(this, new RoutedEventArgs());
+            //            PDFViewerCtrl viewerCtrl = ParentPage?.GetCurrentViewer();
+            //            if (viewerCtrl != null)
+            //            {
+            //                viewerCtrl.IsPageEdit = true;
+            //            }
+            //            dragDoc.Release();
+            //        }
+            //        else
+            //        {
+            //            MessageBoxEx.Show(App.MainPageLoader.GetString("Merge_FileCannotOpenedWarningd"));
+            //        }
+            //        //提示文档损坏无法打开
+            //    }
+            //    else if (!string.IsNullOrEmpty(dragingEnterPath))
+            //    {
+            //        //其他文件  则新增一个页签打开
+            //        //    DragAddTab.Invoke(dragingEnterPath, new RoutedEventArgs());//底层库需要加一个  Load(TPDFDocument)的接口
+            //    }
+            //    MidLane.Visibility = Visibility.Collapsed;
+            //    isDragingEnter = false;
+            //    dragingEnterPath = null;
+            //    return;
+            //}
+            #endregion
+
+            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;
+            }
+            //查找目标数据
+            int targetindex = 0;//目标插入位置
+            if (InsertIndex != -1)
+            {
+                //往前移动时  此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;
+                }
+
+                targetindex = ListPageEdit.Items.IndexOf(targetPerson);
+            }
+
+            List<ListBoxItem> list = new List<ListBoxItem>();
+            List<int> sourceindex = new List<int>();//需要保存每个页面对应的位置
+            //开始排序
+            List<int> pages = new List<int>();
+            //要先对所有选中项 根据页码排序
+            for (int i = 0; i < ListPageEdit.SelectedItems.Count; i++)
+            {
+                var pageindex = ListPageEdit.Items.IndexOf(ListPageEdit.SelectedItems[i] as ListBoxItem);
+                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
+            //}
+            isDraging = false;
+        }
+
+        private void MidLane_Drop(object sender, DragEventArgs e)
+        {
+            ListPageEdit_Drop(sender, e);
+        }
+
+        private void ImgPicture_Drop(object sender, DragEventArgs e)
+        {
+            ListPageEdit_Drop(sender, e);
+        }
+
+        /// <summary>
+        /// 拖拽事件写在外部的Grid里,会更加流畅
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void Grid_DragOver(object sender, DragEventArgs e)
+        {
+            try
+            {
+                //ctrl建按下 不显示插入标记和虚影  因为释放不会响应drop事件
+                if (e.KeyStates == (DragDropKeyStates.ControlKey | DragDropKeyStates.LeftMouseButton) || e.KeyStates == (DragDropKeyStates.ShiftKey | DragDropKeyStates.LeftMouseButton | DragDropKeyStates.ControlKey))
+                    return;
+
+                //滚动后有 位置不准确 要减去滚动偏移量
+                //控制线的位置
+                var pos = e.GetPosition(ListPageEdit);
+                var result = VisualTreeHelper.HitTest(ListPageEdit, pos);
+                if (result == null)
+                {
+                    //MidLane.Visibility = Visibility.Collapsed;
+                    //return;
+                }
+
+                //获取当前鼠标指针下的容器
+                var listBoxItem = CommonHelper.FindVisualParent<ListBoxItem>(result.VisualHit);
+                if (listBoxItem == null)
+                {
+                    //MidLane.Visibility = Visibility.Collapsed;
+                    //return;
+                }
+
+                #region  计算虚影位置
+                //xaml层 要设置 虚影控件为左上
+                double xPos = 0;
+                double yPos = 0;
+                //内部拖动
+                if (!isDragingEnter)
+                {
+                    //Viewbox viewBox = (tempItem.Content as StackPanel).Children[0] as Viewbox;//获取item宽度
+
+                    ImgPicture.Width = tempItem.ActualWidth;
+                    ImgPicture.Height = tempItem.ActualHeight;
+                    ImgPicture.Source = (tempItem.DataContext as PageEditItem).Image;
+                    xPos = e.GetPosition(ListPageEdit).X - item_x;
+                    yPos = e.GetPosition(ListPageEdit).Y - item_y;
+                }
+                //else
+                //{
+                //    //从外部拖入的逻辑
+                //    //var pic = ToBitmapSource(dragingEnterPath);
+                //    //ShadowPicture.Width = pic.Width;
+                //    //ShadowPicture.Height = pic.Height;
+                //    //ShadowPicture.Source = pic;
+                //    //xPos = e.GetPosition(ListPageEdit).X - pic.Width / 2;
+                //    //yPos = e.GetPosition(ListPageEdit).Y - pic.Height / 2;
+                //}
+
+                ImgPicture.Margin = new Thickness(xPos, yPos, 0, 0);
+                #endregion
+
+                #region 计算插入标记位置
+                var scroll = GetScrollHost(ListPageEdit);
+                if (listBoxItem != null)
+                {
+                    //虚拟化影响到该值计算
+                    var p = VisualTreeHelper.GetOffset(listBoxItem);//计算控件在容器中的偏移(位置)
+                    LineInset.Visibility = Visibility.Visible;
+
+                    var panel = GetWrapPanel(ListPageEdit);
+
+                    //var item = panel.ItemSize.Width;
+                    //var item = (ListPageEdit.ItemContainerGenerator.ContainerFromIndex(0) as ListBoxItem).DesiredSize.Width;
+                    var item = listBoxItem.DesiredSize.Width;
+
+                    int count = (int)(panel.ViewportWidth / item);
+                    var gap = (panel.ViewportWidth - count * item) / (count + 1) * 1.0;
+
+                    LineInset.X2 = LineInset.X1 = p.X + gap / 2 + listBoxItem.DesiredSize.Width;
+
+                    if (pos.X < p.X + gap / 2 + listBoxItem.ActualWidth / 2)
+                    {
+                        isFrontHalf = true;//前半部 线条出现在位置前 
+                        LineInset.X2 = LineInset.X1 = p.X - gap / 2;
+                        InsertIndex = ListPageEdit.Items.IndexOf(listBoxItem);
+                    }
+                    else
+                    {
+                        isFrontHalf = false;
+                        InsertIndex = ListPageEdit.Items.IndexOf(listBoxItem) + 1;
+                    }
+                    //MidLane.Y1 = p.Y - scroll.VerticalOffset;//向下滑动后要减去滑动值
+                    LineInset.Y1 = p.Y;
+                    if (LineInset.Y1 < 0)//避免超出上边界
+                    {
+                        LineInset.Y1 = 0;
+                    }
+                    //MidLane.Y2 = p.Y + listBoxItem.ActualHeight - scroll.VerticalOffset;//仿智能滚动后可能会导致 垂直滚动偏量不准确
+                    LineInset.Y2 = p.Y + listBoxItem.ActualHeight;
+                    if (LineInset.Y2 < 0)
+                    {
+                        LineInset.Y2 = 0;
+                    }
+                }
+                #endregion
+
+                //暂时处理  鼠标移出边框时,虚影的显示问题
+                if (pos.Y <= 30 || pos.Y >= ListPageEdit.ActualHeight - 10)
+                {
+                    LineInset.Visibility = Visibility.Collapsed;
+                    needScroll = false;
+                }
+
+                if (pos.X <= 40 || pos.X >= scroll.ViewportWidth - 50)
+                {
+                    LineInset.Visibility = Visibility.Collapsed;
+                    needScroll = false;
+                }
+
+                #region 靠近上下边界时,自动滚动,离边界越近,滚动速度越快
+                speed = 0;
+                if (pos.Y >= ListPageEdit.ActualHeight - 30)
+                {
+                    speed = 30 - (int)(ListPageEdit.ActualHeight - pos.Y);
+                    needScroll = true;
+                }
+                else if (pos.Y <= 30)
+                {
+                    speed = (int)(pos.Y - 30);
+                    needScroll = true;
+                }
+                else
+                    needScroll = false;
+
+                var v = scroll.VerticalOffset;
+                scroll.ScrollToVerticalOffset(v + speed);//触发连续滚动
+                #endregion
+            }
+            catch
+            {
+
+            }
+        }
     }
 }