From 7b6b2a30e615ee19d52d9b99ede448302483b50b Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sun, 15 Feb 2026 01:57:12 +0800 Subject: [PATCH] fix:issue #358 --- Ink Canvas/MainWindow.xaml.cs | 51 ++++++++++++++++--- Ink Canvas/MainWindow_cs/MW_PageListView.cs | 55 ++++++++++++++++++++- 2 files changed, 97 insertions(+), 9 deletions(-) diff --git a/Ink Canvas/MainWindow.xaml.cs b/Ink Canvas/MainWindow.xaml.cs index aa723198..c5b2f2f3 100644 --- a/Ink Canvas/MainWindow.xaml.cs +++ b/Ink Canvas/MainWindow.xaml.cs @@ -202,13 +202,19 @@ namespace Ink_Canvas ShowPage(currentPageIndex); // 手动实现触摸滑动 + const double TouchTapMovementThreshold = 15.0; double leftTouchStartY = 0; + double leftTouchStartX = 0; double leftScrollStartOffset = 0; bool leftIsTouching = false; + bool leftTouchDidScroll = false; BlackBoardLeftSidePageListScrollViewer.TouchDown += (s, e) => { leftIsTouching = true; - leftTouchStartY = e.GetTouchPoint(BlackBoardLeftSidePageListScrollViewer).Position.Y; + leftTouchDidScroll = false; + var pt = e.GetTouchPoint(BlackBoardLeftSidePageListScrollViewer).Position; + leftTouchStartX = pt.X; + leftTouchStartY = pt.Y; leftScrollStartOffset = BlackBoardLeftSidePageListScrollViewer.VerticalOffset; BlackBoardLeftSidePageListScrollViewer.CaptureTouch(e.TouchDevice); e.Handled = true; @@ -217,25 +223,42 @@ namespace Ink_Canvas { if (leftIsTouching) { - double currentY = e.GetTouchPoint(BlackBoardLeftSidePageListScrollViewer).Position.Y; - double delta = leftTouchStartY - currentY; - BlackBoardLeftSidePageListScrollViewer.ScrollToVerticalOffset(leftScrollStartOffset + delta); + var pt = e.GetTouchPoint(BlackBoardLeftSidePageListScrollViewer).Position; + double deltaY = leftTouchStartY - pt.Y; + double deltaX = pt.X - leftTouchStartX; + if (!leftTouchDidScroll && (Math.Abs(deltaY) > TouchTapMovementThreshold || Math.Abs(deltaX) > TouchTapMovementThreshold)) + leftTouchDidScroll = true; + if (leftTouchDidScroll) + BlackBoardLeftSidePageListScrollViewer.ScrollToVerticalOffset(leftScrollStartOffset + deltaY); e.Handled = true; } }; BlackBoardLeftSidePageListScrollViewer.TouchUp += (s, e) => { + if (leftIsTouching && !leftTouchDidScroll) + { + var pt = e.GetTouchPoint(BlackBoardLeftSidePageListScrollViewer).Position; + double dx = pt.X - leftTouchStartX, dy = pt.Y - leftTouchStartY; + if (dx * dx + dy * dy <= TouchTapMovementThreshold * TouchTapMovementThreshold) + TrySwitchWhiteboardPageByTouchPoint(BlackBoardLeftSidePageListView, BlackBoardLeftSidePageListScrollViewer, pt, true); + } leftIsTouching = false; + leftTouchDidScroll = false; BlackBoardLeftSidePageListScrollViewer.ReleaseTouchCapture(e.TouchDevice); e.Handled = true; }; double rightTouchStartY = 0; + double rightTouchStartX = 0; double rightScrollStartOffset = 0; bool rightIsTouching = false; + bool rightTouchDidScroll = false; BlackBoardRightSidePageListScrollViewer.TouchDown += (s, e) => { rightIsTouching = true; - rightTouchStartY = e.GetTouchPoint(BlackBoardRightSidePageListScrollViewer).Position.Y; + rightTouchDidScroll = false; + var pt = e.GetTouchPoint(BlackBoardRightSidePageListScrollViewer).Position; + rightTouchStartX = pt.X; + rightTouchStartY = pt.Y; rightScrollStartOffset = BlackBoardRightSidePageListScrollViewer.VerticalOffset; BlackBoardRightSidePageListScrollViewer.CaptureTouch(e.TouchDevice); e.Handled = true; @@ -244,15 +267,27 @@ namespace Ink_Canvas { if (rightIsTouching) { - double currentY = e.GetTouchPoint(BlackBoardRightSidePageListScrollViewer).Position.Y; - double delta = rightTouchStartY - currentY; - BlackBoardRightSidePageListScrollViewer.ScrollToVerticalOffset(rightScrollStartOffset + delta); + var pt = e.GetTouchPoint(BlackBoardRightSidePageListScrollViewer).Position; + double deltaY = rightTouchStartY - pt.Y; + double deltaX = pt.X - rightTouchStartX; + if (!rightTouchDidScroll && (Math.Abs(deltaY) > TouchTapMovementThreshold || Math.Abs(deltaX) > TouchTapMovementThreshold)) + rightTouchDidScroll = true; + if (rightTouchDidScroll) + BlackBoardRightSidePageListScrollViewer.ScrollToVerticalOffset(rightScrollStartOffset + deltaY); e.Handled = true; } }; BlackBoardRightSidePageListScrollViewer.TouchUp += (s, e) => { + if (rightIsTouching && !rightTouchDidScroll) + { + var pt = e.GetTouchPoint(BlackBoardRightSidePageListScrollViewer).Position; + double dx = pt.X - rightTouchStartX, dy = pt.Y - rightTouchStartY; + if (dx * dx + dy * dy <= TouchTapMovementThreshold * TouchTapMovementThreshold) + TrySwitchWhiteboardPageByTouchPoint(BlackBoardRightSidePageListView, BlackBoardRightSidePageListScrollViewer, pt, false); + } rightIsTouching = false; + rightTouchDidScroll = false; BlackBoardRightSidePageListScrollViewer.ReleaseTouchCapture(e.TouchDevice); e.Handled = true; }; diff --git a/Ink Canvas/MainWindow_cs/MW_PageListView.cs b/Ink Canvas/MainWindow_cs/MW_PageListView.cs index 104d7cb6..a120e198 100644 --- a/Ink Canvas/MainWindow_cs/MW_PageListView.cs +++ b/Ink Canvas/MainWindow_cs/MW_PageListView.cs @@ -1,10 +1,11 @@ -using Ink_Canvas.Helpers; +using Ink_Canvas.Helpers; using System.Collections.ObjectModel; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Ink; using System.Windows.Input; +using System.Windows.Media; namespace Ink_Canvas { @@ -66,6 +67,58 @@ namespace Ink_Canvas BlackBoardRightSidePageListView.SelectedIndex = CurrentWhiteboardIndex - 1; } + private void TrySwitchWhiteboardPageByTouchPoint(ListView listView, ScrollViewer scrollViewer, Point pointInScrollViewer, bool isLeftSide) + { + if (listView == null || scrollViewer == null) return; + try + { + var transform = scrollViewer.TransformToVisual(listView); + if (transform == null) return; + var pointInListView = transform.Transform(pointInScrollViewer); + var hit = VisualTreeHelper.HitTest(listView, pointInListView); + if (hit?.VisualHit == null) return; + var container = FindAncestorOfType(hit.VisualHit); + if (container == null) return; + int index = listView.ItemContainerGenerator.IndexFromContainer(container); + if (index < 0 || index >= blackBoardSidePageListViewObservableCollection.Count) return; + var item = blackBoardSidePageListViewObservableCollection[index]; + if (item == null) return; + AnimationsHelper.HideWithSlideAndFade(BoardBorderLeftPageListView); + AnimationsHelper.HideWithSlideAndFade(BoardBorderRightPageListView); + if (index + 1 != CurrentWhiteboardIndex) + { + if (currentSelectedElement != null) + { + var previousEditingMode = inkCanvas.EditingMode; + UnselectElement(currentSelectedElement); + inkCanvas.EditingMode = previousEditingMode; + currentSelectedElement = null; + } + SaveStrokes(); + ClearStrokes(true); + CurrentWhiteboardIndex = index + 1; + RestoreStrokes(); + UpdateIndexInfoDisplay(); + } + BlackBoardLeftSidePageListView.SelectedIndex = index; + BlackBoardRightSidePageListView.SelectedIndex = index; + } + catch + { + // 忽略命中测试或切换过程中的异常 + } + } + + private static T FindAncestorOfType(DependencyObject current) where T : DependencyObject + { + while (current != null) + { + if (current is T found) return found; + current = VisualTreeHelper.GetParent(current); + } + return null; + } + public static void ScrollViewToVerticalTop(FrameworkElement element, ScrollViewer scrollViewer) { if (element == null || scrollViewer == null)