public
Last active

Mouse Double Click event implementation for Silverlight and Caliburn.Micro

  • Download Gist
DoubleClickEvent
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
public static class DoubleClickEvent
{
public static readonly DependencyProperty AttachActionProperty =
DependencyProperty.RegisterAttached(
"AttachAction",
typeof (string),
typeof (DoubleClickEvent),
new PropertyMetadata(OnAttachActionChanged));
 
public static void SetAttachAction(DependencyObject d, string attachText)
{
d.SetValue(AttachActionProperty, attachText);
}
 
public static string GetAttachAction(DependencyObject d)
{
return d.GetValue(AttachActionProperty) as string;
}
 
private static void OnAttachActionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue == e.OldValue)
return;
 
var text = e.NewValue as string;
if (string.IsNullOrEmpty(text))
return;
 
AttachActionToTarget(text, d);
}
 
private static void AttachActionToTarget(string text, DependencyObject d)
{
var actionMessage = Parser.CreateMessage(d, text);
 
var trigger = new ConditionalEventTrigger
{
EventName = "MouseLeftButtonUp",
Condition = e => DoubleClickCatcher.IsDoubleClick(d, e)
};
trigger.Actions.Add(actionMessage);
 
Interaction.GetTriggers(d).Add(trigger);
}
 
public class ConditionalEventTrigger : EventTrigger
{
public Func<EventArgs, bool> Condition { get; set; }
 
protected override void OnEvent(EventArgs eventArgs)
{
if (Condition(eventArgs))
base.OnEvent(eventArgs);
}
}
 
static class DoubleClickCatcher
{
private const int DoubleClickSpeed = 400;
private const int AllowedPositionDelta = 6;
 
static Point clickPosition;
private static DateTime lastClick = DateTime.Now;
private static bool firstClickDone;
 
internal static bool IsDoubleClick(object sender, EventArgs args)
{
var element = sender as UIElement;
var clickTime = DateTime.Now;
 
var e = args as MouseEventArgs;
if (e == null)
throw new ArgumentException("MouseEventArgs expected");
 
var span = clickTime - lastClick;
 
if (span.TotalMilliseconds > DoubleClickSpeed || firstClickDone == false)
{
clickPosition = e.GetPosition(element);
firstClickDone = true;
lastClick = DateTime.Now;
return false;
}
 
firstClickDone = false;
var position = e.GetPosition(element);
if (Math.Abs(clickPosition.X - position.X) < AllowedPositionDelta &&
Math.Abs(clickPosition.Y - position.Y) < AllowedPositionDelta)
return true;
return false;
}
}
}
UsingInListBox.xaml
XML
1 2 3 4 5 6 7 8
// How to use it in a list box:
 
<ListBox>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding Name}"
Behaviors:DoubleClickEvent.AttachAction="Open($datacontext)">

A bit more detailed description and usage example are in my blog post

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.