Here is a simple static class, MouseButtonHelper, that offers a single method, IsDoubleClick, to determine if a standard MouseLeftButtonDown or MouseLeftButtonUp event is a double click. In the past I have used timers, and Triggers and Behaviors to accomplish the same thing, but this approach is less code, less XAML, and uses a lot less resources.
Usage is as follows:
- In XAML or in code behind, handle the standard MouseLeftButtonDown or MouseLeftButtonUp event for the object you wish to perform double click handling.
- Implement the handler function for the above event as follows:
public void OnMouseButtonDown(object sender, MouseButtonEventArgs e)
{
bool doubleClick = MouseButtonHelper.EventIsDoubleClick(sender, e);
if (doubleClick)
MessageBox.Show("Double click detected!", "Alert", MessageBoxButton.OK);
}
The code below has been tested and used with Silverlight 4.
using System;
using System.Windows;
using System.Windows.Input;
namespace ClassLibrary
{
internal static class MouseButtonHelper
{
private const long k_DoubleClickSpeed = 500;
private const double k_MaxMoveDistance = 10;
private static long _LastClickTicks = 0;
private static Point _LastPosition;
private static WeakReference _LastSender;
internal static bool IsDoubleClick(object sender, MouseButtonEventArgs e)
{
Point position = e.GetPosition(null);
long clickTicks = DateTime.Now.Ticks;
long elapsedTicks = clickTicks - _LastClickTicks;
long elapsedTime = elapsedTicks / TimeSpan.TicksPerMillisecond;
bool quickClick = (elapsedTime <= k_DoubleClickSpeed);
bool senderMatch = (_LastSender != null && sender.Equals(_LastSender.Target));
if (senderMatch && quickClick && position.Distance(_LastPosition) <= k_MaxMoveDistance)
{
// Double click!
_LastClickTicks = 0;
_LastSender = null;
return true;
}
// Not a double click
_LastClickTicks = clickTicks;
_LastPosition = position;
if (!quickClick)
_LastSender = new WeakReference(sender);
return false;
}
private static double Distance(this Point pointA, Point pointB)
{
double x = pointA.X - pointB.X;
double y = pointA.Y - pointB.Y;
return Math.Sqrt(x * x + y * y);
}
}
}