Cleanest single click + double click in Silverlight?

I find various double-click methods, and then the authors click on some if the code is to handle single clicks. Is there a standard in Silverlight 3 that everyone uses to handle both single and double click on lists?

+6
double-click
source share
6 answers

If you use the Reactive Extensions (Rx) library, the code for double-click support is much simpler:

Observable.FromEvent<MouseButtonEventArgs>(myControl, "MouseLeftButtonDown").TimeInterval().Subscribe(evt => { if (evt.Interval.TotalMilliseconds <= 300) { // Do something on double click } }); 
+10
source share

Write once easily using ...

  import YourProject.Utils; //must for using extentions button1.AddDoubleClickHandler((s, e) => { Debug.WriteLine("You can use this DoubleClick extention method for any UIElement in SL !"); }); 

// Here are my utilities

 namespace YourProject.Utils { public class DoubleClick { public DoubleClick() { this._lastClick = DateTime.Now; } private TimeSpan DoubleClickThreshold = TimeSpan.FromMilliseconds(450); private DateTime _lastClick; public event MouseButtonEventHandler MouseDoubleClick; public void DoubleClicked(object sender, MouseButtonEventArgs e) { if (DateTime.Now - this._lastClick <= DoubleClickThreshold) { MouseDoubleClick(sender, e); } this._lastClick = DateTime.Now; } internal void AddHandler(UIElement ctl) { ctl.AddHandler(UIElement.MouseLeftButtonUpEvent, new MouseButtonEventHandler(this.DoubleClicked), true); } } public static class DoubleClickExtentions { public static void AddDoubleClickHandler(this UIElement ctl, MouseButtonEventHandler MouseDoubleClick) { DoubleClick doubleClick = new DoubleClick(); doubleClick.MouseDoubleClick += MouseDoubleClick; doubleClick.AddHandler(ctl); } } } 
+2
source share

I like this approach: http://www.domagoj.pavlesic.com/DoubleClick-in-Silverlight

Pros: you have one click, double click and one-time events with a delay (so you can be sure that there will not be a double click).

+1
source share

I implemented a clean way to record DoubleClick events based on approaches to the following articles:

http://yinyangme.com/blog/post/The-simplest-way-to-detect-DoubleClick-in-Silverlight.aspx http://www.domagoj.pavlesic.com/DoubleClick-in-Silverlight

To use it, you just need to register / unregister the handler using extension methods:

 element.AddDoubleClickHandler(Element_DoubleClick); element.RemoveDoubleClickHandler(Element_DoubleClick); 

Here is the code:

  using System; using System.Windows; using System.Windows.Input; namespace System.Windows { public class DoubleClickHelper { private const long DoubleClickSpeed = 500; private const double 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 <= DoubleClickSpeed); bool senderMatch = (lastSender != null && sender.Equals(lastSender.Target)); if (senderMatch && quickClick && DoubleClickHelper.Distance(position, lastPosition) <= 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(Point pointA, Point pointB) { double x = pointA.X - pointB.X; double y = pointA.Y - pointB.Y; return Math.Sqrt(x * x + y * y); } public bool HasHandlers { get { return this.MouseDoubleClick != null; } } private WeakReference target; public event MouseButtonEventHandler MouseDoubleClick; private void OnMouseDoubleClick(MouseButtonEventArgs args) { if (this.MouseDoubleClick != null && this.target.IsAlive) this.MouseDoubleClick(this.target.Target, args); } public DoubleClickHelper(FrameworkElement target) { this.target = new WeakReference(target); target.MouseLeftButtonDown += target_MouseLeftButtonDown; } void target_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { if (DoubleClickHelper.IsDoubleClick(sender, e)) this.OnMouseDoubleClick(e); } } public static class DoubleClickExtension { public static DoubleClickHelper GetDoubleClickHelper(DependencyObject obj) { return (DoubleClickHelper)obj.GetValue(DoubleClickHelperProperty); } public static void SetDoubleClickHelper(DependencyObject obj, DoubleClickHelper value) { obj.SetValue(DoubleClickHelperProperty, value); } public static readonly DependencyProperty DoubleClickHelperProperty = DependencyProperty.RegisterAttached("DoubleClickHelper", typeof(DoubleClickHelper), typeof(DoubleClickExtension), new PropertyMetadata(null)); public static void AddDoubleClickHandler(this FrameworkElement target, MouseButtonEventHandler handler) { DoubleClickHelper helper = target.GetValue(DoubleClickHelperProperty) as DoubleClickHelper; if (helper == null) { helper = new DoubleClickHelper(target); target.SetValue(DoubleClickHelperProperty, helper); } helper.MouseDoubleClick += handler; } public static void RemoveDoubleClickHandler(this FrameworkElement target, MouseButtonEventHandler handler) { DoubleClickHelper helper = target.GetValue(DoubleClickHelperProperty) as DoubleClickHelper; if (helper == null) return; helper.MouseDoubleClick -= handler; if(!helper.HasHandlers) target.SetValue(DoubleClickHelperProperty, null); } } } 
0
source share

Silverlight 5 has an easier way that MouseButtonEventArgs.ClickCount supports. So you can just attach the normal MouseLeftButtonDown handler and check:

 private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs args) { if (args.ClickCount == 1) return; // handle double-click } 
0
source share

Here is the class that I implemented for controls, as well as the second derived class below for the tree (Silverlight Toolkit). Simply create it using the control you want to check for double clicks and add a handler for the DoubleClicked event. It uses a timer to try to simulate a double-click event. You can change the delay if you think it will work better.

 Public Class DoubleClickHelper Public Event DoubleClicked(ByVal sender As FrameworkElement) Private WithEvents UI As FrameworkElement Sub New(ByRef UI As FrameworkElement) Me.UI = UI UI.AddHandler(UIElement.MouseLeftButtonDownEvent, New MouseButtonEventHandler(AddressOf UI_MouseLeftButtonDown), True) InitTimer() End Sub Public Delay As Single = 0.2 Private _dblclick As Boolean = False Private _timer As New System.Windows.Threading.DispatcherTimer() Protected Property DoubleClick() As Boolean Get Return _dblclick End Get Set(ByVal value As Boolean) _dblclick = value InitTimer() End Set End Property Private Sub InitTimer() RemoveHandler _timer.Tick, AddressOf timer_Tick _timer.Stop() _timer = New System.Windows.Threading.DispatcherTimer() _timer.Interval = TimeSpan.FromSeconds(Delay) AddHandler _timer.Tick, AddressOf timer_Tick _timer.Start() End Sub Protected Overridable Sub timer_Tick(ByVal sender As Object, ByVal e As EventArgs) DoubleClick = False End Sub Protected Overridable Sub UI_MouseLeftButtonDown(ByVal sender As Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles UI.MouseLeftButtonDown If DoubleClick Then HandleDoubleClick(sender) Else HandleFirstClick(sender) End If End Sub Protected Overridable Sub HandleDoubleClick(ByVal sender As FrameworkElement) RaiseEvent DoubleClicked(sender) End Sub Protected Overridable Sub HandleFirstClick(ByVal sender As FrameworkElement) DoubleClick = True End Sub 

Final class

 Public Class TreeViewItemDoubleClickHelper Inherits DoubleClickHelper Private SameSelection As Boolean = False Private WithEvents TreeView As TreeView = Nothing Public Sub New(ByVal TreeView As TreeView) MyBase.New(TreeView) Me.TreeView = TreeView End Sub 'This event happens after MouseLeftButtonDown Private Sub TreeView_SelectedItemChanged(ByVal sender As Object, ByVal e As System.Windows.RoutedPropertyChangedEventArgs(Of Object)) Handles TreeView.SelectedItemChanged SameSelection = e.OldValue Is e.NewValue End Sub Protected Overrides Sub UI_MouseLeftButtonDown(ByVal sender As Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) 'MyBase.UI_MouseLeftButtonDown(sender, e) If DoubleClick Or SameSelection Then HandleDoubleClick(sender) SameSelection = False DoubleClick = False Else HandleFirstClick(sender) End If End Sub 

Final class

-one
source share

All Articles