diff --git a/Ink Canvas/Helpers/MultiPPTInkManager.cs b/Ink Canvas/Helpers/MultiPPTInkManager.cs index 92588601..c4915b05 100644 --- a/Ink Canvas/Helpers/MultiPPTInkManager.cs +++ b/Ink Canvas/Helpers/MultiPPTInkManager.cs @@ -233,6 +233,10 @@ namespace Ink_Canvas.Helpers { return manager.SwitchToSlide(slideIndex, currentStrokes); } + else + { + LogHelper.WriteLogToFile($"无法获取当前墨迹管理器,页面切换失败: {slideIndex}", LogHelper.LogType.Warning); + } } catch (Exception ex) { diff --git a/Ink Canvas/Helpers/PPTInkManager.cs b/Ink Canvas/Helpers/PPTInkManager.cs index 5e14e3f8..afe2077e 100644 --- a/Ink Canvas/Helpers/PPTInkManager.cs +++ b/Ink Canvas/Helpers/PPTInkManager.cs @@ -29,6 +29,11 @@ namespace Ink_Canvas.Helpers private DateTime _inkLockUntil = DateTime.MinValue; private int _lockedSlideIndex = -1; private const int InkLockMilliseconds = 500; + + // 添加快速切换保护机制 + private DateTime _lastSwitchTime = DateTime.MinValue; + private int _lastSwitchSlideIndex = -1; + private const int MinSwitchIntervalMs = 100; // 最小切换间隔100毫秒 #endregion #region Constructor @@ -190,6 +195,15 @@ namespace Ink_Canvas.Helpers { try { + // 检查快速切换保护 + var now = DateTime.Now; + if (now - _lastSwitchTime < TimeSpan.FromMilliseconds(MinSwitchIntervalMs) && + _lastSwitchSlideIndex == slideIndex) + { + LogHelper.WriteLogToFile($"快速切换保护:忽略重复的页面切换请求 {slideIndex}", LogHelper.LogType.Warning); + return LoadSlideStrokes(slideIndex); + } + // 如果有当前墨迹,先保存到正确的页面 if (currentStrokes != null && currentStrokes.Count > 0) { @@ -213,6 +227,11 @@ namespace Ink_Canvas.Helpers // 加载新页面的墨迹 var newStrokes = LoadSlideStrokes(slideIndex); + + // 更新切换记录 + _lastSwitchTime = now; + _lastSwitchSlideIndex = slideIndex; + LogHelper.WriteLogToFile($"已切换到第{slideIndex}页,加载墨迹数量: {newStrokes.Count}", LogHelper.LogType.Trace); return newStrokes; diff --git a/Ink Canvas/MainWindow_cs/MW_PPT.cs b/Ink Canvas/MainWindow_cs/MW_PPT.cs index 8a43a49e..2e65b026 100644 --- a/Ink Canvas/MainWindow_cs/MW_PPT.cs +++ b/Ink Canvas/MainWindow_cs/MW_PPT.cs @@ -92,6 +92,12 @@ namespace Ink_Canvas // 上次播放位置相关字段 private int _lastPlaybackPage = 0; private bool _shouldNavigateToLastPage = false; + + // 页面切换防抖机制 + private DateTime _lastSlideSwitchTime = DateTime.MinValue; + private int _pendingSlideIndex = -1; + private System.Timers.Timer _slideSwitchDebounceTimer; + private const int SlideSwitchDebounceMs = 150; // 防抖延迟150毫秒 #endregion #region PPT Managers @@ -728,11 +734,8 @@ namespace Ink_Canvas var currentSlide = _pptManager?.GetCurrentSlideNumber() ?? 0; var totalSlides = _pptManager?.SlidesCount ?? 0; - // 保存上一页墨迹并加载当前页墨迹 - SwitchSlideInk(currentSlide); - - // 更新UI - _pptUIManager?.UpdateCurrentSlideNumber(currentSlide, totalSlides); + // 使用防抖机制处理页面切换 + HandleSlideSwitchWithDebounce(currentSlide, totalSlides); LogHelper.WriteLogToFile($"幻灯片切换到第{currentSlide}页", LogHelper.LogType.Trace); }); @@ -1011,6 +1014,55 @@ namespace Ink_Canvas } } + /// + /// 使用防抖机制处理页面切换 + /// + private void HandleSlideSwitchWithDebounce(int currentSlide, int totalSlides) + { + try + { + var now = DateTime.Now; + + // 如果距离上次切换时间太短,使用防抖机制 + if (now - _lastSlideSwitchTime < TimeSpan.FromMilliseconds(SlideSwitchDebounceMs)) + { + _pendingSlideIndex = currentSlide; + + // 停止之前的定时器 + _slideSwitchDebounceTimer?.Stop(); + + // 创建新的定时器 + _slideSwitchDebounceTimer = new System.Timers.Timer(SlideSwitchDebounceMs); + _slideSwitchDebounceTimer.Elapsed += (sender, e) => + { + Application.Current.Dispatcher.Invoke(() => + { + if (_pendingSlideIndex > 0) + { + SwitchSlideInk(_pendingSlideIndex); + _pptUIManager?.UpdateCurrentSlideNumber(_pendingSlideIndex, totalSlides); + _pendingSlideIndex = -1; + } + }); + _slideSwitchDebounceTimer?.Stop(); + }; + _slideSwitchDebounceTimer.Start(); + } + else + { + // 直接处理页面切换 + SwitchSlideInk(currentSlide); + _pptUIManager?.UpdateCurrentSlideNumber(currentSlide, totalSlides); + } + + _lastSlideSwitchTime = now; + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"处理页面切换防抖失败: {ex}", LogHelper.LogType.Error); + } + } + private void SwitchSlideInk(int newSlideIndex) { try