Un Trigger per gestire il doppio click anche da ViewModel in Silverlight 4.0

di Alessio Leoncini, in Silverlight 4.0,

A differenza delle applicazioni web, nelle applicazioni desktop è usuale attivare delle funzioni eseguendo il doppio click su un elemento o su un'icona.
Nell'utilizzo di Silverlight per realizzare applicazioni, anche all'interno del browser, ma sempre più simili ad applicazioni installate, può capitare l'esigenza di dover gestire il doppio click del mouse, anche in presenza di un'architettura di tipo Model-View-ViewModel.

Per implementare questa funzione, possiamo estendere la classe TriggerBase, in modo da poter definire il comportamento direttamente da markup, ed associare un ICommand a cui demandare l'effettiva operazione; il trigger può essere implementato in questo modo:

public class DoubleClick : TriggerBase<UIElement>
{
    private readonly DispatcherTimer timer;
    private Point clickPos;

    public DoubleClick()
    {
        timer = new DispatcherTimer();
        timer.Interval = new TimeSpan(0, 0, 0, 0, 300);
        timer.Tick += (o, e) => timer.Stop();
    }

    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.MouseLeftButtonUp += new MouseButtonEventHandler(obj_MouseLeftButtonUp);
    }

    void obj_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        UIElement elem = sender as UIElement;

        if (timer.IsEnabled)
        {
            timer.Stop();
            Point currentPos = e.GetPosition(elem);

            if (Math.Abs(clickPos.X - currentPos.X) < 1
                && Math.Abs(clickPos.Y - currentPos.Y) < 1)
            {
                InvokeActions(null);
            }
        }
        else
        {
            timer.Start();
            clickPos = e.GetPosition(elem);
        }
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.MouseLeftButtonUp -= new MouseButtonEventHandler(obj_MouseLeftButtonUp);

        if (timer.IsEnabled)
            timer.Stop();
    }
}

Come per ogni altro trigger, il suo utilizzo prevede la dichiarazione, sempre nel markup, di un oggetto TriggerAction. Nell'esempio seguente utilizziamo InvokeCommandAction per definire l'ICommand da chiamare a seguito del comportamento del trigger, appunto il doppio click.

<ListBox x:Name="listb1"
            ItemsSource="{Binding ElementsView, Source={StaticResource MenuItemCollection}}">
    <i:Interaction.Triggers>
        <local:DoubleClick>
            <i:InvokeCommandAction Command="{Binding OpenCommand}"
                                    CommandParameter="{Binding SelectedItem, ElementName = listb1}" />
        </local:DoubleClick>
    </i:Interaction.Triggers>
</ListBox>

Grazie al parametro CommandParameter di InvokeCommandAction possiamo passare l'elemento selezionato direttamente alla funzione definita nel ViewModel.

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

Nessuna risorsa collegata

I più letti di oggi