InkCanvas选中笔画后MoveSelected移动功能异常问题排查
问题分析与修复方案
你的问题核心是对MoveSelected(Point)方法的参数理解错误:该方法接收的是笔画需要移动的增量(偏移量),而非目标位置。当前代码错误地将计算出的绝对位置传给它,导致笔画被错误地移动到屏幕边缘。
错误点拆解
- PointerPressed中初始化逻辑错误:
- 错误使用
TransformToVisual计算偏移,存储的_PreviousMousePosition并非光标初始位置,而是光标与选择框的偏移值,后续计算逻辑完全偏离。
- 错误使用
- PointerMoved中移动逻辑错误:
- 计算的
newPosition是绝对位置,而非移动增量,传给MoveSelected后会直接将笔画跳转到该绝对位置;同时更新_PreviousMousePosition为这个绝对位置,导致后续增量计算越来越大,笔画飞速偏移到屏幕边缘。
- 计算的
修复后的代码
1. 调整PointerPressed事件(移动模式初始化)
private void UnprocessedInput_PointerPressed(Windows.UI.Input.Inking.InkUnprocessedInput sender, Windows.UI.Core.PointerEventArgs args) { switch (m_CurrentTool) { case CurrentTool.FreeSelection: if (!m_SelectionBoundingRect.Contains(args.CurrentPoint.RawPosition)) { _Selecting = false; _HasActiveSelection = false; OverlayCanvas.Children.Clear(); } if (!_HasActiveSelection) { m_LassoSel = new Polyline() { StrokeThickness = 2, Stroke = new SolidColorBrush(Windows.UI.Colors.Magenta), StrokeDashArray = new DoubleCollection() { 4, 6, 1, 4 }, Fill = new SolidColorBrush(Windows.UI.Color.FromArgb(50, 255, 0, 255)) }; m_LassoSel.Points.Add(args.CurrentPoint.RawPosition); OverlayCanvas.Children.Add(m_LassoSel); _Selecting = true; break; } else { _WasMoving = true; // 记录按下时的光标绝对位置,用于后续计算移动增量 _PreviousMousePosition = args.CurrentPoint.Position; } break; } }
2. 修正PointerMoved事件(增量计算与移动)
private void UnprocessedInput_PointerMoved(Windows.UI.Input.Inking.InkUnprocessedInput sender, Windows.UI.Core.PointerEventArgs args) { if (_WasMoving) { // 计算当前光标与上一次位置的差值(移动增量) Point delta = new Point( args.CurrentPoint.Position.X - _PreviousMousePosition.X, args.CurrentPoint.Position.Y - _PreviousMousePosition.Y ); // 传入增量移动选中笔画 _SelectionBoundingRect = RenderTarget_ink.InkPresenter.StrokeContainer.MoveSelected(delta); // 更新上一次光标位置为当前位置,用于下一次增量计算 _PreviousMousePosition = args.CurrentPoint.Position; } }
3. 添加PointerReleased事件(重置移动状态)
private void UnprocessedInput_PointerReleased(Windows.UI.Input.Inking.InkUnprocessedInput sender, Windows.UI.Core.PointerEventArgs args) { if (_WasMoving) { _WasMoving = false; } }
额外说明
如果需要实现“光标拖动选择框的某个位置时,笔画移动过程中保持光标相对位置不变”的效果,可以在PointerPressed时计算光标相对于_SelectionBoundingRect的偏移,然后在移动时用当前光标位置减去该偏移得到目标位置,再计算与上一次目标位置的差值作为增量传给MoveSelected,但日常场景中直接使用光标位置增量即可满足需求。
内容的提问来源于stack exchange,提问作者Chadribleu
相关产品推荐
相关产品推荐

