ASP.Net  »  Articoli  »  Silverlight 

Silverlight e la gestione del 'multi-touch'

di: Davide Zordan     07 Aprile 2010

Un passo avanti: abilitare le gesture

Vediamo ora come abilitare delle gesture più complesse mediante l'implementazione di una Silverlight/Blend Behavior che permetta l'abilitazione di un effetto zoom per il controllo a cui viene applicata. Il codice è abbastanza semplice: nel caso in cui il numero di touch points selezionati sia uguale a due, verifichiamo la distanza tra i due punti e applichiamo una ScaleTransform:

Listato 3: TouchAction.Down

private void AssociatedObjectTouchDown(object sender, TouchFrameEventArgs e)
{
  //Initialize the parameters
  this._touchDown = true;
  this.AssociatedObject.Opacity = .75;
  this._tpInitialPoints = e.GetTouchPoints(this.AssociatedObject);
  
  //Initialize the Scale transform
  if (this._scaleTransform == null)
  {
    this._scaleTransform = new ScaleTransform();
    
    if ((this.AssociatedObject.RenderTransform == null) || !(this.AssociatedObject.RenderTransform is TransformGroup))
      this.AssociatedObject.RenderTransform = new TransformGroup();
    
    if (this.AssociatedObject.RenderTransform is TransformGroup)
      (this.AssociatedObject.RenderTransform as TransformGroup).Children.Add(this._scaleTransform);
  }
}

Listato 4: TouchAction.Move

private void AssociatedObjectTouchMove(object sender, TouchFrameEventArgs e)
{
  if (this._touchDown)
  {
    //Find the new points
    TouchPointCollection newPoints = e.GetTouchPoints(AssociatedObject.Parent as FrameworkElement);
    
    if (newPoints!=null && this._tpInitialPoints!=null)
      if (this._tpInitialPoints.Count == 2 && newPoints.Count == 2)
      {
        // Zoom the Control using the ScaleTransform
        double ratio = this.Distance(newPoints.First().Position, newPoints.Last().Position) /           
                       this.Distance(this._tpInitialPoints.First().Position, this._tpInitialPoints.Last().Position);
        
        if (ratio != double.NaN)
        {
          Point midPoint = this.MidPoint(newPoints.First().Position, newPoints.Last().Position);
          this._scaleTransform.CenterX = midPoint.X; this._scaleTransform.CenterY = midPoint.Y;
          this._scaleTransform.ScaleX = ratio; this._scaleTransform.ScaleY = ratio;
        }
      }
  }
}

Listato 5: TouchAction.Up

private void AssociatedObjectTouchUp(object sender, TouchFrameEventArgs e)
{
  // turn off Zoom mode
  this._touchDown = false;
  this.AssociatedObject.Opacity = 1;
}

Ed ecco il codice relativo alla Silverlight/Blend behavior:

Listato 6: Silverlight/Blend behavior

public class TouchZoom : Behavior<FrameworkElement>
{
  protected override void OnAttached()
  {
    base.OnAttached();
    Touch.FrameReported += AssociatedObjectTouchFrameReported;      
  }
  
  protected override void OnDetaching()
  {
    base.OnDetaching();
    Touch.FrameReported -= AssociatedObjectTouchFrameReported;
  }
  
  private void AssociatedObjectTouchFrameReported(object sender, TouchFrameEventArgs e)
  {
    if (this.TouchZoomEnabled)
    {
      TouchPointCollection tpCollection = e.GetTouchPoints(this.AssociatedObject);
      tpCollection.ToList().
        ForEach(tp =>
                        {
                          switch (tp.Action)
                          {
                            case TouchAction.Up:
                              this.AssociatedObjectTouchUp(sender, e);
                              break;
                            case TouchAction.Move:
                              this.AssociatedObjectTouchMove(sender, e);
                              break;
                            case TouchAction.Down:
                              this.AssociatedObjectTouchDown(sender, e);
                              break;
                            }
                        });
    }
  }
}

L'utilizzo della stessa in XAML è quindi molto semplice. Il codice che proponiamo contiene un riferimento ad una ulteriore Behavior denominata TouchDrag che abilita anche il trascinamento dell'oggetto nello schermo con il semplice movimento delle dita. L'implementazione completa è disponibile nel codice allegato all'articolo.

Listato 7: Codice Xaml per il trascinamento dell'oggetto

<UserControl x:Class="SilverlightMultiTouch.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480"
    xmlns:interactivity="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
    xmlns:Behaviors="clr-namespace:SilverlightMultiTouch.Behaviors">
    <Canvas Background="Black">  
        <Canvas>
            <interactivity:Interaction.Behaviors>
                <Behaviors:TouchDrag TouchDragEnabled="True"/>
                <Behaviors:TouchZoom TouchZoomEnabled="True"/>
            </interactivity:Interaction.Behaviors>
            <Image Source="Images/image.png" Height="597" Width="448" Canvas.Left="404" Canvas.Top="96"/>
        </Canvas> 
    </Canvas>
</UserControl>

Guide ASP.Net

Guida Windows Azure Code Snippets

Le migliori pratiche per far girare le applicazioni "in the cloud",...

Guida ASP.NET MVC Best Practices

Un workflow dettagliato e ricco di suggerimenti pratici per...

Guida ASP.NET Starter Kit

Un modo semplice per imparare ad utilizzare le tecnologie Microsoft...

Altre guide

Newsletter @Microsoft Dev

Ogni giovedì, direttamente nella tua e-mail: articoli, guide, tutorial e script ASP, ASP.Net, SQL server e IIS.

Iscriviti alla newsletter

Altre newsletter

Corsi in aula

Corso Progettazione database

11 Maggio 2012 a Milano
Disponibilità: 6 Posti

Amministratore di Reti Windows Server 2008

11 Giugno 2012 a Milano
Disponibilità: 5 Posti

Nessun corso previsto