WPF – 在一段时间内检测鼠标
检测鼠标按钮在特定时间段内按住某个特定元素的最佳方法是什么?
您需要将MouseDown
和MouseUp
处理程序添加到对象。 在MouseDown
记录DateTime.Now
。 如果在MouseUp
处理程序中:
DateTime.Now.Subtract(clickTime).TotalSeconds > your_seconds_value
然后触发一个新事件MouseClickedForXseconds
。
如果您不想等待鼠标MouseDown
事件,则需要在MouseDown
方法上启动计时器,该方法将触发MouseClickedForXSeconds
事件。 此计时器将被鼠标按下事件取消。
感谢您的提示,我已经创建了一个附加属性,以避免任何代码隐藏:
using System; using System.Windows; using System.Windows.Threading; /// /// Represents a particular mouse button being pressed /// public enum MouseButtonType { /// /// Default selection /// None, /// /// Left mouse button /// Left, /// /// Right mouse button /// Right, /// /// Either mouse button /// Both } /// /// Provides functionality for detecting when a mouse button has been held /// public class MouseDownWait { /// /// States which mouse button press should be detected /// public static readonly DependencyProperty MouseButtonProperty = DependencyProperty.RegisterAttached( "MouseButton", typeof(MouseButtonType), typeof(MouseDownWait), new PropertyMetadata( (o, e) => { var ctrl = o as UIElement; if (ctrl != null) { new MouseDownWait(ctrl); } })); /// /// The time (in milliseconds) to wait before detecting mouse press /// public static readonly DependencyProperty TimeProperty = DependencyProperty.RegisterAttached( "Time", typeof(int), typeof(MouseDownWait), new FrameworkPropertyMetadata(0, OnTimePropertyChanged)); /// /// Method to be called when the mouse press is detected /// public static readonly DependencyProperty DetectMethodProperty = DependencyProperty.RegisterAttached( "DetectMethod", typeof(string), typeof(MouseDownWait)); /// /// Target object for the method calls (if not the datacontext) /// public static readonly DependencyProperty MethodTargetProperty = DependencyProperty.RegisterAttached("MethodTarget", typeof(object), typeof(MouseDownWait)); /// /// The timer used to detect mouse button holds /// private static readonly DispatcherTimer Timer = new DispatcherTimer(); /// /// The element containing the attached property /// private readonly UIElement element; /// /// Initializes a new instance of the class. /// /// The element. public MouseDownWait(UIElement element) { this.element = element; if (this.element == null) { return; } this.element.MouseLeftButtonDown += ElementMouseLeftButtonDown; this.element.MouseLeftButtonUp += ElementMouseLeftButtonUp; this.element.MouseRightButtonDown += ElementMouseRightButtonDown; this.element.MouseRightButtonUp += ElementMouseRightButtonUp; this.element.MouseDown += ElementMouseDown; this.element.MouseUp += ElementMouseUp; Timer.Tick += this.TimerTick; } /// /// Gets the mouse button type /// /// The element. /// /// The mouse button type /// public static MouseButtonType GetMouseButton(UIElement element) { return (MouseButtonType)element.GetValue(MouseButtonProperty); } /// /// Sets the mouse button type /// /// The element. /// The type of mouse button public static void SetMouseButton(UIElement element, MouseButtonType value) { element.SetValue(MouseButtonProperty, value); } /// /// Gets the time. /// /// The element. /// The time in milliseconds public static int GetTime(UIElement element) { return (int)element.GetValue(TimeProperty); } /// /// Sets the time. /// /// The element. /// The value. public static void SetTime(UIElement element, int value) { element.SetValue(TimeProperty, value); } /// /// Sets the detect method /// /// The element. /// The value. public static void SetDetectMethod(UIElement element, string value) { element.SetValue(DetectMethodProperty, value); } /// /// Gets the detect method /// /// The element. /// method name public static string GetDetectMethod(UIElement element) { return (string)element.GetValue(DetectMethodProperty); } /// /// Gets the method target. /// /// The CTRL . /// method target (ie viewmodel) public static object GetMethodTarget(UIElement ctrl) { var result = ctrl.GetValue(MethodTargetProperty); if (result == null) { var fe = ctrl as FrameworkElement; if (fe != null) { result = fe.DataContext; } } return result; } /// /// Sets the method target. /// /// The CTRL . /// The value. public static void SetMethodTarget(UIElement ctrl, object value) { ctrl.SetValue(MethodTargetProperty, value); } /// /// Called when the time property changes. /// /// The dependency object. /// The instance containing the event data. private static void OnTimePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { Timer.Interval = TimeSpan.FromMilliseconds((int)e.NewValue); } /// /// Called when a mouse down is detected /// private static void MouseDownDetected() { Timer.Start(); } /// /// Called when a mouse up is detected /// private static void MouseUpDetected() { Timer.Stop(); } /// /// Checks if the mouse button has been detected. /// /// The sender. /// The mouse button type. /// if set to true [mouse down]. private static void CheckMouseDetected(object sender, MouseButtonType type, bool mouseDown) { var uiElement = sender as UIElement; if (uiElement == null) { return; } if (GetMouseButton(uiElement) != type) { return; } if (mouseDown) { MouseDownDetected(); } else { MouseUpDetected(); } } /// /// Called when the mouse down event fires /// /// The sender. /// The instance containing the event data. private static void ElementMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e) { CheckMouseDetected(sender, MouseButtonType.Both, true); } /// /// Called when the mouse up event fires /// /// The sender. /// The instance containing the event data. private static void ElementMouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e) { CheckMouseDetected(sender, MouseButtonType.Both, false); } /// /// Called when the left mouse down event fires /// /// The sender. /// The instance containing the event data. private static void ElementMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e) { CheckMouseDetected(sender, MouseButtonType.Left, true); } /// /// Called when the left mouse up event fires /// /// The sender. /// The instance containing the event data. private static void ElementMouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e) { CheckMouseDetected(sender, MouseButtonType.Left, false); } /// /// Called when the right mouse down event fires /// /// The sender. /// The instance containing the event data. private static void ElementMouseRightButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e) { CheckMouseDetected(sender, MouseButtonType.Right, true); } /// /// Called when the right mouse up event fires /// /// The sender. /// The instance containing the event data. private static void ElementMouseRightButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e) { CheckMouseDetected(sender, MouseButtonType.Right, false); } /// /// Called on each timer tick /// /// The sender. /// The instance containing the event data. private void TimerTick(object sender, EventArgs e) { Timer.Stop(); var method = GetDetectMethod(this.element); if (!string.IsNullOrEmpty(method)) { this.InvokeMethod(method); } } /// /// Invokes the method. /// /// Name of the method. /// The parameters. private void InvokeMethod(string methodName, params object[] parameters) { var target = GetMethodTarget(this.element); var targetMethod = target.GetType().GetMethod(methodName); if (targetMethod == null) { throw new MissingMethodException(methodName); } targetMethod.Invoke(target, parameters); } }
用法:
这将在指定的时间已经过去时调用DataContext(ViewModel)上的方法。 您可以检测鼠标左键,右键或两键。