The event fires when the mouse is clicked twice within a certain time, and within a certain distance. I think the spatial/temporal tolerances make for a smooth user experience. The code consists of static variables to store the position and time of last mouse-click, and extension methods to compare the current values to the stored values. The code should be self-explanatory (While we are one the subject, can anybody point me to a good online code formatter for blogger? Live Writer refuses to install on my machine which has Windows 7 Ultimate, 32-bit):
1: #region Mouse Double Click
2: //initialize to 2 secs back, so event doesnt fire very first time user clicks on control
3: static DateTime _lastClicked = DateTime.Now.AddSeconds(-2);
4: static Point _lastMousePosition = new Point(1, 1);
5: private const double MousePositionTolerance = 20;
6: public static bool IsDoubleClick(this MouseButtonEventArgs e)
7: {
8: bool ret = false;
9: if ((DateTime.Now.Subtract(_lastClicked) < TimeSpan.FromMilliseconds(500))
10: && (e.GetPosition(null).GetDistance(_lastMousePosition) < MousePositionTolerance))
11: {
12: ret = true;
13: }
14: _lastClicked = DateTime.Now;
15: _lastMousePosition = e.GetPosition(null);
16: return ret;
17: }
18: #endregion
19: public static double GetDistance(this Point current, Point other)
20: {
21: double x = current.X - other.X;
22: double y = current.Y - other.Y;
23: return Math.Sqrt(x * x + y * y);
24: }
The consumer code will handle the MouseLeftButtonDown event and examine it to see if it is a double-click, like this:
private void HandleMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.IsDoubleClick())
{
....Caveat Emptor:
The calling method should make sure that all code paths execute e.DoubleClick().
Take, for instance, a calling method like this:
if (condition1 == true)
{
condition1 = false;
do something;
}
else if (e.IsDoubleClick())
{
Do what you do on doubleclick;
}
Here IsDoubleClick is not called the first time the Mousedown event happens, so the static variables _lastPosition and _lastClicked are not set. Hence, IsDoubleClick will not return true when a true double-click happens.
Hope this helps.
Pretty elegant in that it takes advantage of the single threaded nature of silverlight. Thanks for posting the is.
ReplyDeletehey its really nice............and working fine too............
ReplyDeleteVB.net code for same is as.................
#Region "Mouse Double Click"
'initialize to 2 secs back, so event doesnt fire very first time user clicks on control
Dim _lastClicked As DateTime = DateTime.Now.AddSeconds(-2)
Dim _lastMousePosition As New Point(1, 1)
Private Const MousePositionTolerance As Double = 20
_
Public Function IsDoubleClick(e As MouseButtonEventArgs) As Boolean
Dim ret As Boolean = False
If (DateTime.Now.Subtract(_lastClicked) < TimeSpan.FromMilliseconds(500)) AndAlso (e.GetPosition(Nothing).GetDistance(_lastMousePosition) < MousePositionTolerance) Then
ret = True
End If
_lastClicked = DateTime.Now
_lastMousePosition = e.GetPosition(Nothing)
Return ret
End Function
#End Region
_
Public Shared Function GetDistance(current As Point, other As Point) As Double
Dim x As Double = current.X - other.X
Dim y As Double = current.Y - other.Y
Return Math.Sqrt(x * x + y * y)
End Function