using PDF_Office.EventAggregators;
using PDF_Office.Helper;
using PDF_Office.Model.PageEdit;
using Prism.Events;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using WpfToolkit.Controls;
namespace PDF_Office.Views.PageEdit
{
///
/// PageEditContent.xaml 的交互逻辑
///
public partial class PageEditContent : UserControl
{
///
/// 用于通知刷新图片的事件
/// 因为目前的图片刷新策略依赖很多UI事件判断,因为将主要判断逻辑放在UI层,VM负责图片刷新,非必要情况尽量不要采用这种形式
///
private IEventAggregator eventor;
///
/// 暂存的唯一索引值,用于区分多页签
///
private string unicode;
///
/// 是否是加载时第一次触发滚动
///
private bool isFirstScrollChange = true;
///
/// 用于判断滚轮停止的计时器
///
private DispatcherTimer timer = new DispatcherTimer();
///
/// 判断是否开始框选
///
private bool startChoose = false;
///
/// 框选的起始位置
///
private Point starPosition = new Point();
///
/// 记录当前滑块的状态
///
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;
///
/// 是否正在拖拽排序中,通过该变量避免单击触发拖动
///
private bool isDraging = false;
//是否正在从外部拖入文件
private bool isDragingEnter = false;
///
/// 是否需要自动滚动
///
private bool needScroll = false;
//自动滚动速度
private int speed = 0;
public PageEditContent()
{
InitializeComponent();
}
public PageEditContent(IEventAggregator eventAggregator) :this()
{
eventor = eventAggregator;
unicode = App.mainWindowViewModel.SelectedItem.Unicode;
timer.Interval = TimeSpan.FromSeconds(0.3);
timer.Tick += Timer_Tick;
//订阅页面刷新事件
eventor.GetEvent().Subscribe(OneNotifyEvent, e => e.Unicode == unicode);
}
private void Timer_Tick(object sender, EventArgs e)
{
PulishEvent();
timer.Stop();
}
private void OneNotifyEvent(PageEditNotifyEventArgs e)
{
PulishEvent();
}
#region UI事件
///
/// 每次显示的时候就触发事件,刷新所有图片
///
///
///
private void PageEdit_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if((bool)e.NewValue)
{
//当前页面没有发生变化时,刷新图片 这种情况下会拿两次图,需要留意
PulishEvent();
//当前页面发生变化时通过ScrollChanged事件来刷新图片
isFirstScrollChange = true;
}
}
///
/// 鼠标滚轮滚动时触发的事件
///
///
///
private void ListPageEdit_ScrollChanged(object sender, ScrollChangedEventArgs e)
{
if (isFirstScrollChange)
{
PulishEvent();//第一次加载时触发的Scollchange 直接刷新界面,减少白板显示时间
isFirstScrollChange = false;
return;
}
else
{
if (e.VerticalChange != 0)
timer.Start();//暂时找不到比较好的 判断Scroller停止的方法,先用计时器粗略判断
}
}
///
/// 拖动右侧滑块时触发的事件
///
///
///
private void ListPageEdit_Scroll(object sender, System.Windows.Controls.Primitives.ScrollEventArgs e)
{
scrolltype = e.ScrollEventType;
if (scrolltype != System.Windows.Controls.Primitives.ScrollEventType.EndScroll)
{
timer.Stop();
return;
}
PulishEvent();
}
#endregion
#region 方法
///
/// 发布事件
///
private void PulishEvent()
{
var itemSize = (ListPageEdit.Items[0] as PageEditItem).ItemSize;
var range = GetRoughFromView(ListPageEdit, itemSize, new Thickness(5, 10, 5, 10));
eventor.GetEvent().Publish(new PageEditRefreshEventArgs() { Unicode = unicode, PageRange = range });
}
///
/// 获取滑轨的垂直偏移量,结合item总数和Item尺寸以及间隔,来估算实际展示的item范围
/// 返回值为页面范围 从1开始
///
///
///
///
///
private Tuple GetRoughFromView(ListBox view, Size itemSize, Thickness itemMargin)
{
//var scrollViewer = GetScrollHost(view);
var scrollViewer = CommonHelper.FindVisualChild(view);
if (scrollViewer == null || scrollViewer.ActualHeight == 0 || scrollViewer.ActualWidth == 0)//视图展开
return new Tuple(0, 0, 0);
try
{
var currentHeight = scrollViewer.ActualHeight - view.Padding.Top;
var currentWidth = scrollViewer.ActualWidth;
//计算当前窗口大小能显示的行数和列数
var columnCount = (int)(currentWidth / (itemSize.Width + itemMargin.Left));
var rowCount = (int)Math.Ceiling(currentHeight / (itemSize.Height + itemMargin.Bottom));
var preItemCount = (int)((scrollViewer.VerticalOffset / scrollViewer.ExtentHeight) * ((view.Items.Count + columnCount - 1) / columnCount));//滑动百分比*行数 = 大概的垂直位置
preItemCount = preItemCount * columnCount;
var preEnd = (int)(((scrollViewer.VerticalOffset + scrollViewer.ActualHeight) / scrollViewer.ExtentHeight) * ((view.Items.Count + columnCount - 1) / columnCount));
preEnd = preEnd * columnCount + columnCount - 1;
var middle = (int)Math.Ceiling(preItemCount + preEnd / 2d);
return new Tuple(
Math.Max(preItemCount, 0),
Math.Min(view.Items.Count, preEnd),
middle);
}
catch { }
return new Tuple(0, 0, 0);
}
///
/// 获取listbox里的ScrollViewer对象
/// 留意如果有重写ListBox对象,该方法可能无效
///
///
///
private ScrollViewer GetScrollHost(ListBox listBox)
{
if (VisualTreeHelper.GetChildrenCount(listBox) > 0)
{
int s = VisualTreeHelper.GetChildrenCount(listBox);
Border border = VisualTreeHelper.GetChild(listBox, 0) as Border;
if (border != null)
{
return VisualTreeHelper.GetChild(border, 0) as ScrollViewer;
}
}
return null;
}
#endregion
///
/// 输入框显示时,自动获取焦点
///
///
///
private void TextBox_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if((bool)e.NewValue)
{
(sender as Control).Focus();
}
}
private void ListPageEdit_PreviewMouseMove(object sender, MouseEventArgs e)
{
try
{
if (e.LeftButton == MouseButtonState.Pressed)
{
//鼠标框选逻辑
if (startChoose)
{
var position = e.GetPosition(ListPageEdit);
if (position.X < 5 || position.X > ListPageEdit.ActualWidth - 5 || position.Y < 5 || position.Y > ListPageEdit.ActualHeight - 5)
{
startChoose = false;
RectChoose.Visibility = Visibility.Collapsed;
//暂时未想到靠近顶部和底部自动翻滚的好方法,只能先屏蔽这部分功能
Mouse.Capture(null);
return;
}
//矩形框内的item设为选中
DoSelectItems();
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(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
{
LineInset.Visibility = Visibility.Collapsed;
}
}
///
/// 判断是否开始框选、记录框选起始位置
///
///
///
private void ListPageEdit_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var pos = e.GetPosition(ListPageEdit);
HitTestResult result = VisualTreeHelper.HitTest(ListPageEdit, pos);
if (result == null)
{
return;
}
//未选中item 并且不是点击滑轨时 开始框选
var listBoxItem = CommonHelper.FindVisualParent(result.VisualHit);
var scroller = CommonHelper.FindVisualParent(result.VisualHit);
if (listBoxItem == null)
{
if (scroller != null)
{
startChoose = false;
return;
}
//点击空白处时开始框选
startChoose = true;
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;
}
//选中了item 时,不能框选
startChoose = false;
}
private void ListPageEdit_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
startChoose = false;
Mouse.Capture(null);
RectChoose.Visibility = Visibility.Collapsed;
}
///
/// 获取Listobox的Wrappanel容器
///
///
///
public VirtualizingWrapPanel GetWrapPanel(ListBox listBox)
{
Border border = VisualTreeHelper.GetChild(listBox, 0) as Border;
var panel = CommonHelper.FindVisualChild(border);
return panel;
}
///
///根据鼠标拖选的框 选中里面的Item
///
private void DoSelectItems()
{
var s = GetScrollHost(ListPageEdit);
Point start = new Point();
//通过 实时的垂直偏移量和第一次的偏移量抵消,来获取准确的垂直偏移值。
start = new Point(starPosition.X, starPosition.Y - s.VerticalOffset);
var rec = new Rect(start, Mouse.GetPosition(ListPageEdit));
RectChoose.Margin = new Thickness(rec.Left, rec.Top, 0, 0);
RectChoose.Width = rec.Width;
RectChoose.Height = rec.Height;
RectChoose.Visibility = Visibility.Visible;
//检测遍历所有项,筛选在矩形框中的Item
for (int i = 0; i < ListPageEdit.Items.Count; i++)
{
var _item = ListPageEdit.ItemContainerGenerator.ContainerFromIndex(i) as ListBoxItem;
//通过这一步来避免重复误选中
var parent = CommonHelper.FindVisualParent(_item);
if (parent == null)
continue;
var v = VisualTreeHelper.GetOffset(_item);
if (rec.IntersectsWith(new Rect(v.X, v.Y, _item.ActualWidth, _item.ActualHeight)))
{
ListPageEdit.SelectedItems.Add(ListPageEdit.Items[i]);
}
else
{
ListPageEdit.SelectedItems.Remove(ListPageEdit.Items[i]);
}
}
return;
}
///
/// 计算插入标记线和虚影显示
///
///
///
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(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)
{
}
}
///
/// 退出拖拽模式
///
private void ExitDraging()
{
LineInset.Visibility = Visibility.Collapsed;
isDraging = false;
}
///
/// 拖拽释放后的处理逻辑
///
///
///
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(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 list = new List();
List sourceindex = new List();//需要保存每个页面对应的位置
//开始排序
List pages = new List();
//要先对所有选中项 根据页码排序
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();
// 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();
// 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();
// 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);
}
///
/// 拖拽事件写在外部的Grid里,会更加流畅
///
///
///
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(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
{
}
}
}
}