From 8a463d376ab681bfd7b1c15466e8896e32d91f4a Mon Sep 17 00:00:00 2001 From: lindexi Date: Sat, 20 Jun 2020 16:50:08 +0800 Subject: [PATCH] Add InputClickHelper --- .../HandyControl_Shared.projitems | 1 + .../Tools/Helper/Input/InputClickHelper.cs | 163 ++++++++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 src/Shared/HandyControl_Shared/Tools/Helper/Input/InputClickHelper.cs diff --git a/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems b/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems index c0b60db6..f9bdcc45 100644 --- a/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems +++ b/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems @@ -342,6 +342,7 @@ + diff --git a/src/Shared/HandyControl_Shared/Tools/Helper/Input/InputClickHelper.cs b/src/Shared/HandyControl_Shared/Tools/Helper/Input/InputClickHelper.cs new file mode 100644 index 00000000..7119cd3f --- /dev/null +++ b/src/Shared/HandyControl_Shared/Tools/Helper/Input/InputClickHelper.cs @@ -0,0 +1,163 @@ +using System; +using System.Windows; +using System.Windows.Input; + +namespace HandyControl.Tools.Input +{ + /// + /// 输入层点击帮助类 + /// + public static class InputClickHelper + { + /// + /// 将 MouseDown MouseMove MouseUp 封装为点击事件 + /// + /// 要被附加的元素 + /// 点击的事件 + /// 因为拖动而结束点击时触发 + 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; + } + + /// + /// 去掉对 的点击时间的监听 + /// + /// + /// 点击的事件 + /// 因为拖动而结束点击时触发的事件 + 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 readonly DependencyProperty InputInfoProperty = DependencyProperty.RegisterAttached( + "InputInfo", typeof(InputInfo), typeof(InputClickHelper), new PropertyMetadata(default(InputInfo))); + + private static InputInfo GetOrCreateInputInfo(UIElement element) + { + var inputInfo = GetInputInfo(element); + if (inputInfo == null) + { + inputInfo = new InputInfo(); + SetInputInfo(element, inputInfo); + } + + return inputInfo; + } + + private static void SetInputInfo(DependencyObject element, InputInfo value) + { + element.SetValue(InputInfoProperty, value); + } + + private static InputInfo GetInputInfo(DependencyObject element) + { + return (InputInfo) element.GetValue(InputInfoProperty); + } + + private class InputInfo + { + 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 double ToleranceSquared { set; get; } = 0.01; + + public event EventHandler ClickEventHandler; + public event EventHandler DragStarted; + + public bool IsEmpty() => ClickEventHandler is null && DragStarted is null; + + private Point _downedPosition; + private bool _isClick; + } + } +} \ No newline at end of file