improve:墨迹渐隐

This commit is contained in:
2025-09-06 13:16:10 +08:00
parent 41bcae9d05
commit 1a9ddf1969
6 changed files with 757 additions and 65 deletions
+54 -6
View File
@@ -833,12 +833,8 @@ namespace Ink_Canvas.Helpers
// 归一化方向向量
direction.Normalize();
// 使用OpacityMask创建更自然的擦除效果
var maskBrush = CreateEraseMaskBrush(stroke, strokeStart, strokeEnd, 1.0);
visual.OpacityMask = maskBrush;
// 创建擦除动画 - 使用定时器来更新遮罩
StartEraseMaskAnimation(visual, stroke, strokeStart, strokeEnd, duration);
// 创建精确的擦除动画 - 使用PathGeometry来避免变形
CreatePreciseEraseAnimation(visual, stroke, bounds, strokeStart, strokeEnd, direction, length, duration);
}
catch (Exception ex)
{
@@ -848,6 +844,58 @@ namespace Ink_Canvas.Helpers
}
}
/// <summary>
/// 创建精确的擦除动画 - 使用动态裁剪区域避免墨迹移动
/// </summary>
private void CreatePreciseEraseAnimation(UIElement visual, Stroke stroke, Rect bounds, Point strokeStart, Point strokeEnd, Vector direction, double length, int duration)
{
try
{
// 计算擦除方向上的移动距离
var totalDistance = Math.Sqrt(Math.Pow(strokeEnd.X - strokeStart.X, 2) + Math.Pow(strokeEnd.Y - strokeStart.Y, 2));
if (totalDistance == 0)
{
// 如果墨迹没有长度,使用简单渐隐
StartSimpleFadeAnimation(visual, stroke, visual.Opacity, duration);
return;
}
// 创建动态裁剪区域 - 从完整墨迹开始,逐渐缩小
var clipGeometry = new RectangleGeometry
{
Rect = bounds
};
visual.Clip = clipGeometry;
// 创建擦除动画 - 裁剪区域从起点向终点移动并缩小
// 使用更自然的擦除效果:从起点开始,逐渐向终点移动
var eraseAnimation = new RectAnimation
{
From = bounds, // 从完整边界开始
To = new Rect(strokeEnd.X, strokeEnd.Y, 0, bounds.Height), // 到终点位置,宽度为0
Duration = TimeSpan.FromMilliseconds(duration),
EasingFunction = new CubicEase { EasingMode = EasingMode.EaseInOut }
};
// 添加动画完成事件
eraseAnimation.Completed += (sender, e) =>
{
OnAnimationCompleted(visual, stroke);
};
// 开始动画
clipGeometry.BeginAnimation(RectangleGeometry.RectProperty, eraseAnimation);
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"精确擦除动画失败: {ex}", LogHelper.LogType.Error);
// 失败时回退到简单动画
StartSimpleFadeAnimation(visual, stroke, visual.Opacity, duration);
}
}
/// <summary>
/// 动画完成后的统一处理
/// </summary>
+43 -56
View File
@@ -155,6 +155,22 @@ namespace Ink_Canvas.Helpers
{
// 更新创建时间,使其成为最新的窗口
windowInfo.CreatedTime = DateTime.Now;
// 立即将窗口置顶
var hwnd = new WindowInteropHelper(window).Handle;
if (hwnd != IntPtr.Zero)
{
SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_SHOWWINDOW | SWP_NOOWNERZORDER);
// 确保窗口样式正确
int exStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
if ((exStyle & WS_EX_TOPMOST) == 0)
{
SetWindowLong(hwnd, GWL_EXSTYLE, exStyle | WS_EX_TOPMOST);
}
}
ApplyZOrder();
}
}
@@ -165,64 +181,12 @@ namespace Ink_Canvas.Helpers
/// </summary>
private static void ApplyZOrder()
{
// 按创建时间排序,最新的窗口在最后
var sortedWindows = _windowStack
.Where(w => IsWindow(w.Handle) && IsWindowVisible(w.Handle) && !IsIconic(w.Handle))
.OrderBy(w => w.CreatedTime)
.ToList();
if (sortedWindows.Count == 0) return;
// 获取主窗口(第一个注册的窗口)
var mainWindow = sortedWindows.FirstOrDefault();
if (mainWindow == null) return;
// 如果主窗口需要置顶且启用了无焦点模式
if (mainWindow.IsTopmost && mainWindow.IsNoFocusMode)
// 简化逻辑:直接设置所有窗口为置顶,让Windows系统自然处理层级
foreach (var windowInfo in _windowStack.ToList())
{
// 检查是否有子窗口在前景
var foregroundWindow = GetForegroundWindow();
var hasChildWindowInForeground = false;
if (foregroundWindow != mainWindow.Handle)
{
var foregroundWindowProcessId = GetWindowThreadProcessId(foregroundWindow, out uint processId);
var currentProcessId = GetCurrentProcessId();
if (processId == currentProcessId)
{
// 检查前景窗口是否在我们的窗口列表中
var foregroundWindowInfo = sortedWindows.FirstOrDefault(w => w.Handle == foregroundWindow);
if (foregroundWindowInfo != null)
{
hasChildWindowInForeground = true;
}
}
}
if (!hasChildWindowInForeground)
{
// 没有子窗口在前景,主窗口置顶
SetWindowPos(mainWindow.Handle, HWND_TOPMOST, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_SHOWWINDOW | SWP_NOOWNERZORDER);
// 确保主窗口样式正确
int exStyle = GetWindowLong(mainWindow.Handle, GWL_EXSTYLE);
if ((exStyle & WS_EX_TOPMOST) == 0)
{
SetWindowLong(mainWindow.Handle, GWL_EXSTYLE, exStyle | WS_EX_TOPMOST);
}
}
}
// 处理其他窗口的层级
for (int i = 1; i < sortedWindows.Count; i++)
{
var windowInfo = sortedWindows[i];
// 子窗口应该置顶于主窗口
if (windowInfo.IsTopmost)
if (windowInfo.IsTopmost && IsWindow(windowInfo.Handle) && IsWindowVisible(windowInfo.Handle) && !IsIconic(windowInfo.Handle))
{
// 设置窗口为置顶
SetWindowPos(windowInfo.Handle, HWND_TOPMOST, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_SHOWWINDOW | SWP_NOOWNERZORDER);
@@ -273,5 +237,28 @@ namespace Ink_Canvas.Helpers
return _windowStack.Count;
}
}
/// <summary>
/// 强制刷新所有窗口的置顶状态
/// </summary>
public static void ForceRefreshAllWindows()
{
lock (_lockObject)
{
foreach (var windowInfo in _windowStack.ToList())
{
if (windowInfo.IsTopmost && IsWindow(windowInfo.Handle))
{
// 强制设置窗口为置顶
SetWindowPos(windowInfo.Handle, HWND_TOPMOST, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_SHOWWINDOW | SWP_NOOWNERZORDER);
// 确保窗口样式正确
int exStyle = GetWindowLong(windowInfo.Handle, GWL_EXSTYLE);
SetWindowLong(windowInfo.Handle, GWL_EXSTYLE, exStyle | WS_EX_TOPMOST);
}
}
}
}
}
}
+292 -2
View File
@@ -16,6 +16,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;
@@ -246,6 +247,9 @@ namespace Ink_Canvas
// 为浮动栏按钮添加触摸事件支持
AddTouchSupportToFloatingBarButtons();
// 为滑块控件添加触摸事件支持
AddTouchSupportToSliders();
}
@@ -1755,6 +1759,9 @@ namespace Ink_Canvas
// 先设置WPF的Topmost属性
Topmost = true;
// 立即应用置顶
WindowZOrderManager.BringToTop(this);
// 如果启用了无焦点模式,需要特殊处理
if (Settings.Advanced.IsNoFocusMode)
{
@@ -1847,8 +1854,8 @@ namespace Ink_Canvas
// 检查是否有子窗口在前景
if (!WindowZOrderManager.HasChildWindowInForeground())
{
// 没有子窗口在前景,重新应用Z-Order
WindowZOrderManager.SetWindowTopmost(this, true);
// 没有子窗口在前景,强制刷新所有窗口的置顶状态
WindowZOrderManager.ForceRefreshAllWindows();
}
}
catch (Exception ex)
@@ -2227,5 +2234,288 @@ namespace Ink_Canvas
LogHelper.WriteLogToFile($"设置工具模式时出错: {ex.Message}", LogHelper.LogType.Error);
}
}
#region
/// <summary>
/// 为所有滑块控件添加触摸和手写笔事件支持
/// </summary>
private void AddTouchSupportToSliders()
{
try
{
// 获取所有滑块控件并添加触摸支持
var sliders = new List<Slider>
{
InkFadeTimeSlider,
AutoStraightenLineThresholdSlider,
LineStraightenSensitivitySlider,
LineEndpointSnappingThresholdSlider,
ViewboxFloatingBarScaleTransformValueSlider,
ViewboxFloatingBarOpacityValueSlider,
ViewboxFloatingBarOpacityInPPTValueSlider,
PPTButtonLeftPositionValueSlider,
PPTButtonRightPositionValueSlider,
PPTButtonLBPositionValueSlider,
PPTButtonRBPositionValueSlider,
TouchMultiplierSlider,
NibModeBoundsWidthSlider,
FingerModeBoundsWidthSlider,
SideControlMinimumAutomationSlider,
RandWindowOnceCloseLatencySlider,
RandWindowOnceMaxStudentsSlider,
BoardInkWidthSlider,
BoardInkAlphaSlider,
BoardHighlighterWidthSlider,
InkWidthSlider,
InkAlphaSlider,
HighlighterWidthSlider
};
foreach (var slider in sliders)
{
if (slider != null)
{
AddTouchSupportToSlider(slider);
}
}
LogHelper.WriteLogToFile("已为所有滑块控件添加触摸支持", LogHelper.LogType.Trace);
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"添加滑块触摸支持时出错: {ex.Message}", LogHelper.LogType.Error);
}
}
/// <summary>
/// 为单个滑块控件添加触摸和手写笔事件支持
/// </summary>
/// <param name="slider">要添加触摸支持的滑块控件</param>
private void AddTouchSupportToSlider(Slider slider)
{
if (slider == null) return;
// 启用触摸和手写笔支持
slider.IsManipulationEnabled = true;
// 添加触摸事件
slider.TouchDown += Slider_TouchDown;
slider.TouchMove += Slider_TouchMove;
slider.TouchUp += Slider_TouchUp;
// 添加手写笔事件
slider.StylusDown += Slider_StylusDown;
slider.StylusMove += Slider_StylusMove;
slider.StylusUp += Slider_StylusUp;
// 添加操作事件(用于更精确的触摸控制)
slider.ManipulationStarted += Slider_ManipulationStarted;
slider.ManipulationDelta += Slider_ManipulationDelta;
slider.ManipulationCompleted += Slider_ManipulationCompleted;
}
/// <summary>
/// 滑块触摸按下事件处理
/// </summary>
private void Slider_TouchDown(object sender, TouchEventArgs e)
{
var slider = sender as Slider;
if (slider == null) return;
// 捕获触摸设备
slider.CaptureTouch(e.TouchDevice);
// 计算触摸位置对应的滑块值
var touchPoint = e.GetTouchPoint(slider);
UpdateSliderValueFromPosition(slider, touchPoint.Position);
e.Handled = true;
}
/// <summary>
/// 滑块触摸移动事件处理
/// </summary>
private void Slider_TouchMove(object sender, TouchEventArgs e)
{
var slider = sender as Slider;
if (slider == null) return;
// 计算触摸位置对应的滑块值
var touchPoint = e.GetTouchPoint(slider);
UpdateSliderValueFromPosition(slider, touchPoint.Position);
e.Handled = true;
}
/// <summary>
/// 滑块触摸释放事件处理
/// </summary>
private void Slider_TouchUp(object sender, TouchEventArgs e)
{
var slider = sender as Slider;
if (slider == null) return;
// 释放触摸捕获
slider.ReleaseTouchCapture(e.TouchDevice);
e.Handled = true;
}
/// <summary>
/// 滑块手写笔按下事件处理
/// </summary>
private void Slider_StylusDown(object sender, StylusDownEventArgs e)
{
var slider = sender as Slider;
if (slider == null) return;
// 捕获手写笔设备
slider.CaptureStylus();
// 计算手写笔位置对应的滑块值
var stylusPoint = e.GetStylusPoints(slider);
if (stylusPoint.Count > 0)
{
UpdateSliderValueFromPosition(slider, stylusPoint[0].ToPoint());
}
e.Handled = true;
}
/// <summary>
/// 滑块手写笔移动事件处理
/// </summary>
private void Slider_StylusMove(object sender, StylusEventArgs e)
{
var slider = sender as Slider;
if (slider == null || !slider.IsStylusCaptured) return;
// 计算手写笔位置对应的滑块值
var stylusPoint = e.GetStylusPoints(slider);
if (stylusPoint.Count > 0)
{
UpdateSliderValueFromPosition(slider, stylusPoint[0].ToPoint());
}
e.Handled = true;
}
/// <summary>
/// 滑块手写笔释放事件处理
/// </summary>
private void Slider_StylusUp(object sender, StylusEventArgs e)
{
var slider = sender as Slider;
if (slider == null) return;
// 释放手写笔捕获
slider.ReleaseStylusCapture();
e.Handled = true;
}
/// <summary>
/// 滑块操作开始事件处理
/// </summary>
private void Slider_ManipulationStarted(object sender, ManipulationStartedEventArgs e)
{
var slider = sender as Slider;
if (slider == null) return;
e.Handled = true;
}
/// <summary>
/// 滑块操作变化事件处理
/// </summary>
private void Slider_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
{
var slider = sender as Slider;
if (slider == null) return;
// 计算操作位置对应的滑块值
var manipulationOrigin = e.ManipulationOrigin;
UpdateSliderValueFromPosition(slider, manipulationOrigin);
e.Handled = true;
}
/// <summary>
/// 滑块操作完成事件处理
/// </summary>
private void Slider_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
{
var slider = sender as Slider;
if (slider == null) return;
e.Handled = true;
}
/// <summary>
/// 根据触摸/手写笔位置更新滑块值
/// </summary>
/// <param name="slider">滑块控件</param>
/// <param name="position">触摸/手写笔位置</param>
private void UpdateSliderValueFromPosition(Slider slider, Point position)
{
if (slider == null) return;
try
{
// 计算滑块轨道的位置和长度
var track = slider.Template.FindName("PART_Track", slider) as Track;
if (track == null) return;
var thumb = track.Thumb;
if (thumb == null) return;
// 获取滑块轨道的实际渲染位置
track.Arrange(new Rect(track.DesiredSize));
thumb.Arrange(new Rect(thumb.DesiredSize));
// 计算相对位置(0-1之间)
double relativePosition = 0;
if (slider.Orientation == System.Windows.Controls.Orientation.Horizontal)
{
// 水平滑块
var trackWidth = track.ActualWidth;
if (trackWidth > 0)
{
relativePosition = Math.Max(0, Math.Min(1, position.X / trackWidth));
}
}
else
{
// 垂直滑块
var trackHeight = track.ActualHeight;
if (trackHeight > 0)
{
relativePosition = Math.Max(0, Math.Min(1, position.Y / trackHeight));
}
}
// 计算新的滑块值
var newValue = slider.Minimum + relativePosition * (slider.Maximum - slider.Minimum);
// 如果启用了吸附到刻度,则调整到最近的刻度
if (slider.IsSnapToTickEnabled && slider.TickFrequency > 0)
{
var tickCount = (int)((slider.Maximum - slider.Minimum) / slider.TickFrequency);
var tickIndex = (int)Math.Round(relativePosition * tickCount);
newValue = slider.Minimum + tickIndex * slider.TickFrequency;
}
// 更新滑块值
slider.Value = Math.Max(slider.Minimum, Math.Min(slider.Maximum, newValue));
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"更新滑块值时出错: {ex.Message}", LogHelper.LogType.Error);
}
}
#endregion
}
}
@@ -944,7 +944,11 @@ namespace Ink_Canvas
AnimationsHelper.HideWithSlideAndFade(BoardBorderTools);
AnimationsHelper.HideWithSlideAndFade(BoardImageOptionsPanel);
new RandWindow(Settings).Show();
var randWindow = new RandWindow(Settings);
randWindow.Show();
// 确保窗口显示后立即置顶
randWindow.Activate();
WindowZOrderManager.BringToTop(randWindow);
}
public void CheckEraserTypeTab()
+15
View File
@@ -35,6 +35,9 @@ namespace Ink_Canvas
// 添加窗口关闭事件处理
Closed += RandWindow_Closed;
// 添加窗口显示事件处理
Loaded += RandWindow_Loaded;
}
private void LoadBackground(Settings settings)
@@ -86,6 +89,9 @@ namespace Ink_Canvas
// 添加窗口关闭事件处理
Closed += RandWindow_Closed;
// 添加窗口显示事件处理
Loaded += RandWindow_Loaded;
new Thread(() =>
{
@@ -349,6 +355,15 @@ namespace Ink_Canvas
}
}
/// <summary>
/// 窗口加载事件处理
/// </summary>
private void RandWindow_Loaded(object sender, RoutedEventArgs e)
{
// 窗口加载完成后,立即将其置顶
WindowZOrderManager.BringToTop(this);
}
/// <summary>
/// 窗口关闭事件处理
/// </summary>
@@ -218,6 +218,9 @@ namespace Ink_Canvas.Windows {
_selectedSidebarItemName = "CanvasAndInkItem";
UpdateSidebarItemsSelection();
// 为自定义滑块控件添加触摸支持
AddTouchSupportToCustomSliders();
}
@@ -594,5 +597,350 @@ namespace Ink_Canvas.Windows {
}
}
}
#region
/// <summary>
/// 为自定义滑块控件添加触摸和手写笔事件支持
/// </summary>
private void AddTouchSupportToCustomSliders()
{
try
{
// 延迟执行,确保UI元素已加载
Dispatcher.BeginInvoke(new Action(() =>
{
// 查找所有自定义滑块控件并添加触摸支持
AddTouchSupportToCustomSliderInPane(CanvasAndInkPane);
AddTouchSupportToCustomSliderInPane(ThemePane);
AddTouchSupportToCustomSliderInPane(PowerPointPane);
AddTouchSupportToCustomSliderInPane(AutomationPane);
AddTouchSupportToCustomSliderInPane(LuckyRandomPane);
AddTouchSupportToCustomSliderInPane(AdvancedPane);
}), System.Windows.Threading.DispatcherPriority.Loaded);
}
catch (Exception ex)
{
// 记录错误但不影响程序运行
System.Diagnostics.Debug.WriteLine($"添加自定义滑块触摸支持时出错: {ex.Message}");
}
}
/// <summary>
/// 为指定面板中的自定义滑块控件添加触摸支持
/// </summary>
/// <param name="pane">面板控件</param>
private void AddTouchSupportToCustomSliderInPane(Grid pane)
{
if (pane == null) return;
// 查找面板中的所有自定义滑块控件
var customSliders = FindCustomSlidersInPanel(pane);
foreach (var slider in customSliders)
{
AddTouchSupportToCustomSlider(slider);
}
}
/// <summary>
/// 在面板中查找自定义滑块控件
/// </summary>
/// <param name="panel">面板控件</param>
/// <returns>自定义滑块控件列表</returns>
private List<CustomSliderInfo> FindCustomSlidersInPanel(DependencyObject panel)
{
var customSliders = new List<CustomSliderInfo>();
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(panel); i++)
{
var child = VisualTreeHelper.GetChild(panel, i);
// 检查是否是自定义滑块控件(包含GnomeSliderThumb图片的Grid
if (child is Grid grid)
{
var customSlider = FindCustomSliderInGrid(grid);
if (customSlider != null)
{
customSliders.Add(customSlider);
}
}
// 递归查找子元素
customSliders.AddRange(FindCustomSlidersInPanel(child));
}
return customSliders;
}
/// <summary>
/// 在Grid中查找自定义滑块控件
/// </summary>
/// <param name="grid">Grid控件</param>
/// <returns>自定义滑块信息</returns>
private CustomSliderInfo FindCustomSliderInGrid(Grid grid)
{
// 查找包含GnomeSliderThumb图片的Grid
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(grid); i++)
{
var child = VisualTreeHelper.GetChild(grid, i);
if (child is Image image && image.Source != null)
{
var sourceName = image.Source.ToString();
if (sourceName.Contains("GnomeSliderThumb"))
{
// 找到滑块控件,创建自定义滑块信息
var customSlider = new CustomSliderInfo
{
Container = grid,
ThumbImage = image,
TrackBorder = FindTrackBorderInGrid(grid),
ValueBorder = FindValueBorderInGrid(grid)
};
return customSlider;
}
}
}
return null;
}
/// <summary>
/// 在Grid中查找轨道Border
/// </summary>
/// <param name="grid">Grid控件</param>
/// <returns>轨道Border</returns>
private Border FindTrackBorderInGrid(Grid grid)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(grid); i++)
{
var child = VisualTreeHelper.GetChild(grid, i);
if (child is Border border && border.Background != null)
{
var brush = border.Background as SolidColorBrush;
if (brush != null && brush.Color.ToString() == "#FFDEDEDE")
{
return border;
}
}
}
return null;
}
/// <summary>
/// 在Grid中查找值显示Border
/// </summary>
/// <param name="grid">Grid控件</param>
/// <returns>值显示Border</returns>
private Border FindValueBorderInGrid(Grid grid)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(grid); i++)
{
var child = VisualTreeHelper.GetChild(grid, i);
if (child is Border border && border.Background != null)
{
var brush = border.Background as SolidColorBrush;
if (brush != null && brush.Color.ToString() == "#FF3584E4")
{
return border;
}
}
}
return null;
}
/// <summary>
/// 为自定义滑块控件添加触摸支持
/// </summary>
/// <param name="customSlider">自定义滑块信息</param>
private void AddTouchSupportToCustomSlider(CustomSliderInfo customSlider)
{
if (customSlider?.Container == null) return;
// 启用触摸和手写笔支持
customSlider.Container.IsManipulationEnabled = true;
// 添加触摸事件
customSlider.Container.TouchDown += (s, e) => CustomSlider_TouchDown(s, e, customSlider);
customSlider.Container.TouchMove += (s, e) => CustomSlider_TouchMove(s, e, customSlider);
customSlider.Container.TouchUp += (s, e) => CustomSlider_TouchUp(s, e, customSlider);
// 添加手写笔事件
customSlider.Container.StylusDown += (s, e) => CustomSlider_StylusDown(s, e, customSlider);
customSlider.Container.StylusMove += (s, e) => CustomSlider_StylusMove(s, e, customSlider);
customSlider.Container.StylusUp += (s, e) => CustomSlider_StylusUp(s, e, customSlider);
// 添加操作事件
customSlider.Container.ManipulationStarted += (s, e) => CustomSlider_ManipulationStarted(s, e, customSlider);
customSlider.Container.ManipulationDelta += (s, e) => CustomSlider_ManipulationDelta(s, e, customSlider);
customSlider.Container.ManipulationCompleted += (s, e) => CustomSlider_ManipulationCompleted(s, e, customSlider);
}
/// <summary>
/// 自定义滑块触摸按下事件处理
/// </summary>
private void CustomSlider_TouchDown(object sender, TouchEventArgs e, CustomSliderInfo customSlider)
{
customSlider.Container.CaptureTouch(e.TouchDevice);
customSlider.IsTouchCaptured = true;
var touchPoint = e.GetTouchPoint(customSlider.Container);
UpdateCustomSliderValueFromPosition(customSlider, touchPoint.Position);
e.Handled = true;
}
/// <summary>
/// 自定义滑块触摸移动事件处理
/// </summary>
private void CustomSlider_TouchMove(object sender, TouchEventArgs e, CustomSliderInfo customSlider)
{
// 检查是否有触摸捕获
if (!customSlider.IsTouchCaptured) return;
var touchPoint = e.GetTouchPoint(customSlider.Container);
UpdateCustomSliderValueFromPosition(customSlider, touchPoint.Position);
e.Handled = true;
}
/// <summary>
/// 自定义滑块触摸释放事件处理
/// </summary>
private void CustomSlider_TouchUp(object sender, TouchEventArgs e, CustomSliderInfo customSlider)
{
customSlider.Container.ReleaseTouchCapture(e.TouchDevice);
customSlider.IsTouchCaptured = false;
e.Handled = true;
}
/// <summary>
/// 自定义滑块手写笔按下事件处理
/// </summary>
private void CustomSlider_StylusDown(object sender, StylusDownEventArgs e, CustomSliderInfo customSlider)
{
customSlider.Container.CaptureStylus();
var stylusPoint = e.GetStylusPoints(customSlider.Container);
if (stylusPoint.Count > 0)
{
UpdateCustomSliderValueFromPosition(customSlider, stylusPoint[0].ToPoint());
}
e.Handled = true;
}
/// <summary>
/// 自定义滑块手写笔移动事件处理
/// </summary>
private void CustomSlider_StylusMove(object sender, StylusEventArgs e, CustomSliderInfo customSlider)
{
if (!customSlider.Container.IsStylusCaptured) return;
var stylusPoint = e.GetStylusPoints(customSlider.Container);
if (stylusPoint.Count > 0)
{
UpdateCustomSliderValueFromPosition(customSlider, stylusPoint[0].ToPoint());
}
e.Handled = true;
}
/// <summary>
/// 自定义滑块手写笔释放事件处理
/// </summary>
private void CustomSlider_StylusUp(object sender, StylusEventArgs e, CustomSliderInfo customSlider)
{
customSlider.Container.ReleaseStylusCapture();
e.Handled = true;
}
/// <summary>
/// 自定义滑块操作开始事件处理
/// </summary>
private void CustomSlider_ManipulationStarted(object sender, ManipulationStartedEventArgs e, CustomSliderInfo customSlider)
{
e.Handled = true;
}
/// <summary>
/// 自定义滑块操作变化事件处理
/// </summary>
private void CustomSlider_ManipulationDelta(object sender, ManipulationDeltaEventArgs e, CustomSliderInfo customSlider)
{
var manipulationOrigin = e.ManipulationOrigin;
UpdateCustomSliderValueFromPosition(customSlider, manipulationOrigin);
e.Handled = true;
}
/// <summary>
/// 自定义滑块操作完成事件处理
/// </summary>
private void CustomSlider_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e, CustomSliderInfo customSlider)
{
e.Handled = true;
}
/// <summary>
/// 根据触摸/手写笔位置更新自定义滑块值
/// </summary>
/// <param name="customSlider">自定义滑块信息</param>
/// <param name="position">触摸/手写笔位置</param>
private void UpdateCustomSliderValueFromPosition(CustomSliderInfo customSlider, Point position)
{
if (customSlider?.TrackBorder == null || customSlider.ThumbImage == null) return;
try
{
// 计算滑块轨道的实际位置和长度
var trackWidth = customSlider.TrackBorder.ActualWidth;
if (trackWidth <= 0) return;
// 计算相对位置(0-1之间)
var relativePosition = Math.Max(0, Math.Min(1, position.X / trackWidth));
// 更新滑块位置
var thumbTransform = customSlider.ThumbImage.RenderTransform as TranslateTransform;
if (thumbTransform == null)
{
thumbTransform = new TranslateTransform();
customSlider.ThumbImage.RenderTransform = thumbTransform;
}
// 计算新的滑块位置
var newX = relativePosition * trackWidth;
thumbTransform.X = newX;
// 更新值显示Border的宽度
if (customSlider.ValueBorder != null)
{
var valueWidth = relativePosition * trackWidth;
customSlider.ValueBorder.Width = Math.Max(0, valueWidth);
// 调整值显示Border的位置
var valueMargin = customSlider.ValueBorder.Margin;
customSlider.ValueBorder.Margin = new Thickness(0, valueMargin.Top, trackWidth - valueWidth, valueMargin.Bottom);
}
// 这里可以根据需要添加值变化事件处理
// 例如:OnCustomSliderValueChanged(customSlider, relativePosition);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"更新自定义滑块值时出错: {ex.Message}");
}
}
/// <summary>
/// 自定义滑块信息类
/// </summary>
private class CustomSliderInfo
{
public Grid Container { get; set; }
public Image ThumbImage { get; set; }
public Border TrackBorder { get; set; }
public Border ValueBorder { get; set; }
public bool IsTouchCaptured { get; set; } = false;
}
#endregion
}
}