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:
private void MyMap_MouseClick(object sender, Map.MouseEventArgs e)
{
e.Handled = true;
bool doubleClick = MouseButtonHelper.IsDoubleClick(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.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace Mapping.ArcGIS
{
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, ESRI.ArcGIS.Client.Map.MouseEventArgs e)
{
Point position = e.ScreenPoint;
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);
}
}
}