Doble Click en Silverlight usando Behaviors

Silverlight no tiene soporte en los UIElement para el evento Doble Click. Pero con Silverlight 3 y Blend 3 es sencillo desarrollar una solución genérica para todos los UIElement y extenderlos con el evento Doble Click.

Para ello usaremos la librería System.Windows.Interactivity que se encuentra en el SDK de Expression Blend 3 (%programfiles%Microsoft SDKsExpressionblend InteractivityLibrariesSilverlight”). Una vez que ya tengamos esa librería referenciada en nuestro proyecto, debemos crear un Behavior:

using System.Windows;
using System.Windows.Interactivity;

public class MouseDoubleClickBehavior : Behavior<UIElement>
{
    
}

Como veis lo hacemos genérico para cualquier UIElement, ya que es la clase base de todos los elementos que tienen los eventos del ratón. Para trabajar con los Behavoirs debemos sobrescribir varios métodos de la clase base:

private AutomationPeer Peer { get; set; }

protected override void OnAttached()
{
    Peer = FrameworkElementAutomationPeer.FromElement(AssociatedObject) ??
           FrameworkElementAutomationPeer.CreatePeerForElement(AssociatedObject);

    AssociatedObject.MouseLeftButtonUp += AssociatedObject_MouseLeftButtonUp;
    base.OnAttached();
}

protected override void OnDetaching()
{
    AssociatedObject.MouseLeftButtonUp -= AssociatedObject_MouseLeftButtonUp;
    base.OnDetaching();
}

Con estos métodos podemos controlar cuando el Behavior se asociada y se desasocia, debemos usar la clase AutimationPeer para darle funcionalidad al objeto AssociatedObject. Y ese mismo objeto de tipo UIElement es con el que nos subscribiremos al evento MouseLeftButton. Como veis tenemos ahí el controlador AssociatedObject_MouseLeftButtonUp, que el que dará la lógica a nuestro behavior:

private bool _waiting;
private DateTime _waitingSince;

private void AssociatedObject_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    if (_waiting)
    {
        if (DateTime.Now.Subtract(_waitingSince).Milliseconds < Interval)
            OnMouseDoubleClick(e);
        _waiting = false;
    }
    else
    {
        _waiting = true;
        _waitingSince = DateTime.Now;
    }
}

private void OnMouseDoubleClick(MouseButtonEventArgs args)
{
    if (MouseDoubleClick != null)
        MouseDoubleClick(AssociatedObject, args);
}

public event MouseButtonEventHandler MouseDoubleClick;
private int _interval = 500;
public int Interval
{
    get { return _interval; }
    set { _interval = value; }
}

La lógica como veis es sencilla, hemos creado el evento MouseDoubleClick y en caso de que ya hayamos hecho un Click y el tiempo sea menor al que le establecemos en la propiedad Interval (Por defecto le pongo 500), el evento será lanzado.

Con esto ya podríamos en el XAML hacer algo parecido a los siguiente:

<Image>
	<i:Interaction.Behaviors>
		<my:MouseDoubleClickBehavior
            MouseDoubleClick="MouseDoubleClick" 
            Interval="500" />
	</i:Interaction.Behaviors>
</Image>

Y así ya podríamos añadirlo a todos los controles que deriven de UIElement que tengamos.

En otro artículo os comentaré como solucionar el Scroll con el Mouse Wheel usando otro Behavior 😉

4 thoughts on “Doble Click en Silverlight usando Behaviors

  1. Si, pero a mi me gusta más la tuya Oskar, suelo preferir los sencillo a lo complejo, esta solución está muy bien pero es más «complejilla»

    Enhorabuena a los dos

  2. El problema, es que Silverlight no tiene ese ClickCount 😉

    Ese es el motivo por el que hay que buscar otra solución. Y bueno, realmente no es tan compleja esta solución. Mantiene la tendencia que vienen llevando desde la aparación de WPF y es la interación mediante la subscripción a eventos.

    En este caso un objeto se subscribe a otro (OnAttached()) y entonces podemos interactuar con él. Realmente esto podríamos hacerlo por cada control que queramos que tenga «doble click» pero con esto es arrastrar un elemento en el Blend 😉

Responder a eecsaky Cancelar respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *