149 lines
5.2 KiB
C#
149 lines
5.2 KiB
C#
using System;
|
|
using System.Windows;
|
|
using System.Windows.Input;
|
|
|
|
namespace HandyControl.Tools
|
|
{
|
|
/// <summary>
|
|
/// 输入层点击帮助类
|
|
/// </summary>
|
|
public static class InputClickHelper
|
|
{
|
|
private static readonly DependencyProperty InputInfoProperty = DependencyProperty.RegisterAttached(
|
|
"InputInfo", typeof(InputInfo), typeof(InputClickHelper), new PropertyMetadata(default(InputInfo)));
|
|
|
|
private static void SetInputInfo(DependencyObject element, InputInfo value) => element.SetValue(InputInfoProperty, value);
|
|
|
|
private static InputInfo GetInputInfo(DependencyObject element) => (InputInfo)element.GetValue(InputInfoProperty);
|
|
|
|
/// <summary>
|
|
/// 将 MouseDown MouseMove MouseUp 封装为点击事件
|
|
/// </summary>
|
|
/// <param name="element">要被附加的元素</param>
|
|
/// <param name="clickEventHandler">点击的事件</param>
|
|
/// <param name="dragStarted">因为拖动而结束点击时触发</param>
|
|
public static void AttachMouseDownMoveUpToClick(UIElement element, EventHandler clickEventHandler,
|
|
EventHandler dragStarted = null)
|
|
{
|
|
var inputInfo = GetOrCreateInputInfo(element);
|
|
inputInfo.ClickEventHandler += clickEventHandler;
|
|
|
|
inputInfo.DragStarted += dragStarted;
|
|
|
|
element.MouseDown -= Element_MouseDown;
|
|
element.MouseDown += Element_MouseDown;
|
|
element.MouseMove -= Element_MouseMove;
|
|
element.MouseMove += Element_MouseMove;
|
|
element.MouseUp -= Element_MouseUp;
|
|
element.MouseUp += Element_MouseUp;
|
|
element.LostMouseCapture -= Element_LostMouseCapture;
|
|
element.LostMouseCapture += Element_LostMouseCapture;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 去掉对 <paramref name="element" /> 的点击时间的监听
|
|
/// </summary>
|
|
/// <param name="element"></param>
|
|
/// <param name="clickEventHandler">点击的事件</param>
|
|
/// <param name="dragStarted">因为拖动而结束点击时触发的事件</param>
|
|
public static void DetachMouseDownMoveUpToClick(UIElement element, EventHandler clickEventHandler,
|
|
EventHandler dragStarted = null)
|
|
{
|
|
var inputInfo = GetInputInfo(element);
|
|
if (inputInfo == null) return;
|
|
|
|
inputInfo.ClickEventHandler -= clickEventHandler;
|
|
inputInfo.DragStarted -= dragStarted;
|
|
|
|
if (inputInfo.IsEmpty())
|
|
{
|
|
element.ClearValue(InputInfoProperty);
|
|
element.MouseDown -= Element_MouseDown;
|
|
element.MouseMove -= Element_MouseMove;
|
|
element.MouseUp -= Element_MouseUp;
|
|
element.LostMouseCapture -= Element_LostMouseCapture;
|
|
}
|
|
}
|
|
|
|
private static void Element_LostMouseCapture(object sender, MouseEventArgs e)
|
|
{
|
|
var element = (UIElement)sender;
|
|
GetInputInfo(element)?.LostCapture();
|
|
}
|
|
|
|
private static void Element_MouseUp(object sender, MouseButtonEventArgs e)
|
|
{
|
|
var element = (UIElement)sender;
|
|
GetInputInfo(element)?.Up(e.GetPosition(element));
|
|
}
|
|
|
|
private static void Element_MouseMove(object sender, MouseEventArgs e)
|
|
{
|
|
var element = (UIElement)sender;
|
|
GetInputInfo(element)?.Move(e.GetPosition(element));
|
|
}
|
|
|
|
private static void Element_MouseDown(object sender, MouseButtonEventArgs e)
|
|
{
|
|
var element = (UIElement)sender;
|
|
GetInputInfo(element)?.Down(e.GetPosition(element));
|
|
}
|
|
|
|
private static InputInfo GetOrCreateInputInfo(UIElement element)
|
|
{
|
|
var inputInfo = GetInputInfo(element);
|
|
if (inputInfo == null)
|
|
{
|
|
inputInfo = new InputInfo();
|
|
SetInputInfo(element, inputInfo);
|
|
}
|
|
|
|
return inputInfo;
|
|
}
|
|
|
|
private class InputInfo
|
|
{
|
|
private const double ToleranceSquared = 0.01;
|
|
|
|
private Point _downedPosition;
|
|
|
|
private bool _isClick;
|
|
|
|
public event EventHandler ClickEventHandler;
|
|
|
|
public event EventHandler DragStarted;
|
|
|
|
public void Down(Point position)
|
|
{
|
|
_downedPosition = position;
|
|
_isClick = true;
|
|
}
|
|
|
|
public void Move(Point position)
|
|
{
|
|
if (!_isClick) return;
|
|
|
|
if ((position - _downedPosition).LengthSquared > ToleranceSquared)
|
|
{
|
|
_isClick = false;
|
|
DragStarted?.Invoke(null, EventArgs.Empty);
|
|
}
|
|
}
|
|
|
|
public void Up(Point position)
|
|
{
|
|
_isClick = _isClick && (position - _downedPosition).LengthSquared <= ToleranceSquared;
|
|
|
|
if (!_isClick) return;
|
|
|
|
ClickEventHandler?.Invoke(null, EventArgs.Empty);
|
|
|
|
_isClick = false;
|
|
}
|
|
|
|
public void LostCapture() => _isClick = false;
|
|
|
|
public bool IsEmpty() => ClickEventHandler is null && DragStarted is null;
|
|
}
|
|
}
|
|
} |