Gestire il doppio-click Con Silverlight 4 e MVVM

Grazie al buon Ale forse ho raggiunto una soluzione intelligente e che mi piace. Lo scopo era quello di gestire il doppio-click all’interno di un’applicazione Silverlight 4 senza troppi fronzoli, e potendo sfruttare il tutto in un’ottica Model-View-ViewModel, quindi senza alcun codice nel code-behind delle Page.

Il tutto parte da questo post, segnalatomi questa mattina da Alessandro, appunto. 🙂

Il codice del post implementa un DoubleClickTrigger, da inserire poi come child di un qualsiasi componente grafico della nostra pagina, come StackPanel, TextBlock e così via. Voglio solo riproporre qui solo una parte del codice di quell’articolo, ovvero il gestore dell’evento OnMouseButtonDown:

private void OnMouseButtonDown(object sender, MouseButtonEventArgs e)
{
    if (!timer.IsEnabled)
    {
        timer.Start();
        return;
    }
 
    timer.Stop();
 
    // Qui si scatena il doppio-click, eseguo quello che devo eseguire
}

E’ piuttosto semplice: al primo MouseDown parte un piccolo Timer da 200ms. Se l’utente clicca nuovamente entro questo tempo, significa che è avvenuto un DoubleClick, e quindi raggiungiamo la riga di codice che qui sopra vedete commentata. Se mettessimo una MessageBox.Show(“”);, a tutti gli effetti sul doppio-click appare il vostro messaggio.

In un’ottica M-V-VM, però, sappiamo benissimo che tutto ciò che deve essere eseguito deve essere contenuto nella nostra classe ViewModel. La soluzione in questo caso è usare una attached-property, che permette di attaccare ad un componente grafico una qualsiasi istanza di ICommand, anche dove solitamente non sarebbe possibile. Ed ecco quindi poche righe di codice che lo rendono possibile:

public static class ControlsCommandHelper
{
    public static DependencyProperty CommandProperty = DependencyProperty.RegisterAttached("Command",
        typeof(ICommand),
        typeof(ControlsCommandHelper),
        new PropertyMetadata(null));
 
    public static void SetCommand(DependencyObject target, ICommand value)
    {
        target.SetValue(ControlsCommandHelper.CommandProperty, value);
    }
 
    public static ICommand GetCommand(DependencyObject target)
    {
        return (ICommand)target.GetValue(CommandProperty);
    }
}

 

A questo punto l’event handler sopra diventa:

private void OnMouseButtonDown(object sender, MouseButtonEventArgs e)
{
    if (!timer.IsEnabled)
    {
        timer.Start();
        return;
    }
 
    timer.Stop();
 
    UIElement element = sender as UIElement;
 
    if (element != null)
    {
        ICommand command = element.GetValue(ControlsCommandHelper.CommandProperty) as ICommand;
 
        if (command != null)
        {
            command.Execute(null);
        }
    }
}

 

Morale: quando avviene un DoubleClick, prendo lo UIElement che ha scatenato l’evento, recupero la sua attached property Command e – se tutto va a buon fine – semplicemente eseguo il comando. In questo caso passo null all’Execute(), altrimenti dovrei gestire anche il CommandParameter.

Quindi, niente code-behind. Il tutto può essere inserito, come dicevo all’inizio, anche all’interno di un DataTemplate di una ListBox, quindi questa tecnica può essere benissimo utilizzata per reagire al doppio-click, lavorando sul SelectedItem della ListBox stessa.

screenshots

Rimane solo il problema dei 200ms, che non mi piacciono perchè dovrebbe essere l’OS che si prende cura di dirmi quando è avvenuto un doppio-click. Anche perchè un utente può andare nel pannello di controllo e allungare/diminuire il tempo considerato per il doppio-click, e così facendo lo ignoro e basta.

Ecco comunque un piccolo codice sorgente che può essere utile.

Send to Kindle

Igor Damiani

La sua passione per l'informatica nasce nella prima metà degli anni '80, quando suo padre acquistò un Texas Instruments TI-99. Da allora ha continuato a seguire l'evoluzione sia hardware che software avvenuta nel corso degli anni. E' un utente, un videogiocatore ed uno sviluppatore software a tempo pieno. Igor ha lavorato e lavora anche oggi con le più moderne tecnologie Microsoft per lo sviluppo di applicazioni: .NET Framework, XAML, Universal Windows Platform, su diverse piattaforme, tra cui spiccano Windows 10 piattaforme mobile. Numerose sono le app che Igor ha creato e pubblicato sul marketplace sotto il nome VivendoByte, suo personale marchio di fabbrica. Adora mantenere i contatti attraverso Twitter e soprattutto attraverso gli eventi delle community .NET.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.