fix(UI): 优化弹出菜单位置和层级管理
修复弹出菜单在移动时位置不更新的问题,添加节流机制避免频繁刷新 使用Win32 API强制刷新弹出菜单位置并提升到最顶层 调整浮动工具栏和弹出菜单的样式和位置 移除未使用的字体样式定义
This commit is contained in:
@@ -7,6 +7,7 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Ink;
|
||||
using System.Windows.Input;
|
||||
@@ -205,6 +206,7 @@ namespace Ink_Canvas
|
||||
/// </summary>
|
||||
private Point pointPPT = new Point(-1, -1);
|
||||
private DispatcherTimer _floatingBarScreenFollowTimer;
|
||||
private DispatcherTimer _popupRefreshTimer; // Popup 位置刷新节流定时器
|
||||
private string _lastFloatingBarScreenDeviceName;
|
||||
private string _lastCanvasScreenDeviceName;
|
||||
private bool _isRebuildingCanvasForScreen;
|
||||
@@ -227,6 +229,95 @@ namespace Ink_Canvas
|
||||
pointPPT = new Point(xPos, yPos);
|
||||
else
|
||||
pointDesktop = new Point(xPos, yPos);
|
||||
|
||||
// 刷新 Popup 菜单位置(带节流)
|
||||
RefreshPopupPositionThrottled();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 刷新 Popup 菜单位置(带节流,避免频繁调用)
|
||||
/// </summary>
|
||||
private void RefreshPopupPositionThrottled()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 如果没有打开的 Popup,直接返回
|
||||
if (!BorderTools.IsOpen && !BoardBorderToolsPopup.IsOpen) return;
|
||||
|
||||
// 如果定时器不存在,创建一个(16ms ≈ 60fps)
|
||||
if (_popupRefreshTimer == null)
|
||||
{
|
||||
_popupRefreshTimer = new DispatcherTimer();
|
||||
_popupRefreshTimer.Interval = TimeSpan.FromMilliseconds(16);
|
||||
_popupRefreshTimer.Tick += (s, e) =>
|
||||
{
|
||||
_popupRefreshTimer?.Stop();
|
||||
RefreshPopupPositionInternal();
|
||||
};
|
||||
}
|
||||
|
||||
// 重启定时器(如果已经在运行,会重新计时)
|
||||
_popupRefreshTimer.Stop();
|
||||
_popupRefreshTimer.Start();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"RefreshPopupPositionThrottled error: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 实际执行 Popup 位置刷新(强力版本)
|
||||
/// </summary>
|
||||
private void RefreshPopupPositionInternal()
|
||||
{
|
||||
try
|
||||
{
|
||||
RefreshPopupForcefully(BorderTools);
|
||||
RefreshPopupForcefully(BoardBorderToolsPopup);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"RefreshPopupPositionInternal error: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 强制刷新单个 Popup 的位置
|
||||
/// 使用多种策略确保位置更新生效
|
||||
/// </summary>
|
||||
private void RefreshPopupForcefully(Popup popup)
|
||||
{
|
||||
if (popup == null || !popup.IsOpen || popup.PlacementTarget == null) return;
|
||||
|
||||
try
|
||||
{
|
||||
// 策略1:强制失效测量和布局
|
||||
popup.InvalidateMeasure();
|
||||
popup.InvalidateArrange();
|
||||
|
||||
// 策略2:修改 Offset 触发重新定位
|
||||
var originalHorizontalOffset = popup.HorizontalOffset;
|
||||
var originalVerticalOffset = popup.VerticalOffset;
|
||||
|
||||
popup.HorizontalOffset = originalHorizontalOffset + 0.001;
|
||||
popup.VerticalOffset = originalVerticalOffset + 0.001;
|
||||
|
||||
popup.HorizontalOffset = originalHorizontalOffset;
|
||||
popup.VerticalOffset = originalVerticalOffset;
|
||||
|
||||
// 策略3:强制更新布局
|
||||
popup.UpdateLayout();
|
||||
|
||||
// 策略4:使用 Win32 API 强制刷新窗口位置(终极方案)
|
||||
AnimationsHelper.ForceRefreshPopupPosition(popup);
|
||||
|
||||
System.Diagnostics.Debug.WriteLine($"[PopupRefresh] Forcefully refreshed popup position");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"[PopupRefresh] Error: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user