zoukankan      html  css  js  c++  java
  • Doubleclicking in Silverlight

    Mike Snow recently posted an article on how to do double clicks in Silverlight. However, his approach isn't very reusable, doesn't allow for multiple listeners and doesn't check to see if the mouse moved between the two clicks. Below is my solution, which uses extension methods and attached properties to track clicks and event handlers.

    To use it, first include the namespace in your code:

    using MyApplication.Extensions;
    

    This will add AddDoubleClick and RemoveDoubleClick methods to any UIElement. You can then add an event handler to your element like so:

    MyDblClickElement.AddDoubleClick(MyDblClickElement_MouseDoubleClick);
    

    The double click handler signature is the same as for mouse down. Example:

    private void MyDblClickElement_MouseDoubleClick(object sender, MouseButtonEventArgs e)
    {
    Point position = e.GetPosition(this);
    MessageBox.Show(string.Format("dblclick at {0},{1}", position.X, position.Y));
    } 
    

    Here's the code:

    using System;
    using System.Collections.Generic;
    using System.Windows;
    using System.Windows.Input;
    using System.Windows.Threading;
    namespace MyApplication.Extensions
    {
        public static class Mouse
        {
            private const int doubleClickInterval = 200;
            private static readonly DependencyProperty DoubleClickTimerProperty = DependencyProperty.RegisterAttached("DoubleClickTimer", typeof(DispatcherTimer), typeof(UIElement), null);
            private static readonly DependencyProperty DoubleClickHandlersProperty = DependencyProperty.RegisterAttached("DoubleClickHandlers", typeof(List<MouseButtonEventHandler>), typeof(UIElement), null);
            private static readonly DependencyProperty DoubleClickPositionProperty = DependencyProperty.RegisterAttached("DoubleClickPosition", typeof(Point), typeof(UIElement), null);
            /// <summary>
            /// Adds a double click event handler.
            /// </summary>
            /// <param name="element">The Element to listen for double clicks on.</param>
            /// <param name="handler">The handler.</param>
            public static void AddDoubleClick(this UIElement element, MouseButtonEventHandler handler)
            {
                element.MouseLeftButtonDown += element_MouseLeftButtonDown;
                List<MouseButtonEventHandler> handlers;
                handlers = element.GetValue(DoubleClickHandlersProperty) as List<MouseButtonEventHandler>;
                if (handlers == null)
                {
                    handlers = new List<MouseButtonEventHandler>();
                    element.SetValue(DoubleClickHandlersProperty, handlers);
                }
                handlers.Add(handler);
            }
            /// <summary>
            /// Removes a double click event handler.
            /// </summary>
            /// <param name="element">The element.</param>
            /// <param name="handler">The handler.</param>
            public static void RemoveDoubleClick(this UIElement element, MouseButtonEventHandler handler)
            {
                element.MouseLeftButtonDown -= element_MouseLeftButtonDown;
                List<MouseButtonEventHandler> handlers = element.GetValue(DoubleClickHandlersProperty) as List<MouseButtonEventHandler>;
                if (handlers != null)
                {
                    handlers.Remove(handler);
                    if (handlers.Count == 0)
                        element.ClearValue(DoubleClickHandlersProperty);
                }
            }
            private static void element_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                UIElement element = sender as UIElement;
                Point position = e.GetPosition(element);
                DispatcherTimer timer = element.GetValue(DoubleClickTimerProperty) as DispatcherTimer;
                if (timer != null) //DblClick
                {
                    timer.Stop();
                    Point oldPosition = (Point)element.GetValue(DoubleClickPositionProperty);
                    element.ClearValue(DoubleClickTimerProperty);
                    element.ClearValue(DoubleClickPositionProperty);
                    if (Math.Abs(oldPosition.X - position.X) < 1 && Math.Abs(oldPosition.Y - position.Y) < 1) //mouse didn't move => Valid double click
                    {
                        List<MouseButtonEventHandler> handlers = element.GetValue(DoubleClickHandlersProperty) as List<MouseButtonEventHandler>;
                        if (handlers != null)
                        {
                            foreach (MouseButtonEventHandler handler in handlers)
                            {
                                handler(sender, e);
                            }
                        }
                        return;
                    }
                }
                //First click or mouse moved. Start a new timer
                timer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(doubleClickInterval) };
                timer.Tick += new EventHandler((s, args) =>
                {  //DblClick timed out
                    (s as DispatcherTimer).Stop();
                    element.ClearValue(DoubleClickTimerProperty); //clear timer
                    element.ClearValue(DoubleClickPositionProperty); //clear first click position
                });
                element.SetValue(DoubleClickTimerProperty, timer);
                element.SetValue(DoubleClickPositionProperty, position);
                timer.Start();
            }
        }
    }
    
     

  • 相关阅读:
    MV*模式的个人理解
    Unlink of file '.git/objects/pack/pack-***.pack' failed. Should I try again? (y/n) (转)
    不定宽高元素的水平垂直居中
    判断是否在微信浏览器中
    HTML5实战与剖析之触摸事件(touchstart、touchmove和touchend)(转)
    清除inline-block元素间距
    rs485多主
    基于状态机的单片机按键短按长按功能的实现
    深入理解FIFO(包含有FIFO深度的解释)——转载
    传递指针的指针(错误的例子)
  • 原文地址:https://www.cnblogs.com/HeroBeast/p/1559409.html
Copyright © 2011-2022 走看看