Procedura dettagliata: creazione della prima applicazione a tocco

WPF consente alle applicazioni di rispondere al tocco. È ad esempio possibile interagire con un'applicazione utilizzando uno o più dita su un dispositivo sensibile al tocco, ad esempio un touchscreen. In questa procedura dettagliata viene creata un'applicazione che consente all'utente di spostarsi, ridimensionare o ruotare un singolo oggetto tramite tocco.

Prerequisiti

Per completare la procedura dettagliata, è necessario disporre dei componenti seguenti:

  • Microsoft Visual Studio 2010.

  • Windows 7.

  • Un dispositivo in grado di accettare l'input tocco, ad esempio un touchscreen che supporta Windows Touch.

È inoltre necessario disporre di una conoscenza di base della modalità di creazione di un'applicazione in WPF, in particolare della modalità di sottoscrizione e di gestione di un evento. Per ulteriori informazioni, vedere Procedura dettagliata: introduzione a WPF.

Creazione dell'applicazione

Per creare l'applicazione

  1. Creare un nuovo progetto di applicazione WPF in Visual Basic o Visual C# denominato BasicManipulation. Per ulteriori informazioni, vedere Procedura: creare un nuovo progetto di applicazione WPF.

  2. Sostituire il contenuto di MainWindow.xaml con il codice XAML riportato di seguito.

    Questo markup consente di creare un'applicazione semplice contenente un oggetto Rectangle di colore rosso su un oggetto Canvas. La proprietà IsManipulationEnabled di Rectangle viene impostata su true in modo che possa ricevere gli eventi di modifica. L'applicazione sottoscrive gli eventi ManipulationStarting, ManipulationDelta e ManipulationInertiaStarting. Questi eventi contengono la logica per spostare Rectangle quando l'utente lo modifica.

    <Window x:Class="BasicManipulation.MainWindow"
            xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
            Title="Move, Size, and Rotate the Square"
            WindowState="Maximized"
            ManipulationStarting="Window_ManipulationStarting"
            ManipulationDelta="Window_ManipulationDelta"
            ManipulationInertiaStarting="Window_InertiaStarting">
      <Window.Resources>
    
        <!--The movement, rotation, and size of the Rectangle is 
            specified by its RenderTransform.-->
        <MatrixTransform x:Key="InitialMatrixTransform">
          <MatrixTransform.Matrix>
            <Matrix OffsetX="200" OffsetY="200"/>
          </MatrixTransform.Matrix>
        </MatrixTransform>
    
      </Window.Resources>
    
      <Canvas>
        <Rectangle Fill="Red" Name="manRect"
                     Width="200" Height="200" 
                     RenderTransform="{StaticResource InitialMatrixTransform}"
                     IsManipulationEnabled="true" />
      </Canvas>
    </Window>
    
    
  3. Se si utilizza Visual Basic, nella prima riga di MainWindow.xaml sostituire x:Class="BasicManipulation.MainWindow" con x:Class="MainWindow".

  4. Nella classe MainWindow aggiungere il gestore eventi ManipulationStarting.

    L'evento ManipulationStarting si verifica quando WPF rileva l'inizio della modifica di un oggetto tramite input tocco. Nel codice viene specificato che la posizione della modifica deve essere relativa a Window impostando la proprietà ManipulationContainer.

    Private Sub Window_ManipulationStarting(ByVal sender As Object, ByVal e As ManipulationStartingEventArgs)
        e.ManipulationContainer = Me
        e.Handled = True
    End Sub
    
    void Window_ManipulationStarting(object sender, ManipulationStartingEventArgs e)
    {
        e.ManipulationContainer = this;
        e.Handled = true;
    }
    
  5. Nella classe MainWindow aggiungere il gestore eventi ManipulationDelta.

    L'evento ManipulationDelta si verifica quando la posizione viene modificata tramite input tocco e può verificarsi più volte durante la modifica. L'evento può inoltre verificarsi dopo il sollevamento di un dito. Ad esempio, se l'utente sposta un dito su uno schermo, l'evento ManipulationDelta si verifica più volte durante lo spostamento del dito. Quando l'utente solleva un dito dallo schermo, l'evento ManipulationDelta continua a verificarsi per simulare l'inerzia.

    Nel codice viene applicata la proprietà DeltaManipulation alla proprietà RenderTransform dell'oggetto Rectangle in modo da spostarlo mentre l'utente sposta l'input tocco. Viene inoltre verificato se l'oggetto Rectangle si trova al di fuori dei limiti dell'oggetto Window quando l'evento si verifica durante l'inerzia. In caso affermativo, l'applicazione chiama il metodo ManipulationDeltaEventArgs.Complete per terminare la modifica.

    Private Sub Window_ManipulationDelta(ByVal sender As Object, ByVal e As ManipulationDeltaEventArgs)
    
        ' Get the Rectangle and its RenderTransform matrix.
        Dim rectToMove As Rectangle = e.OriginalSource
        Dim rectTransform As MatrixTransform = rectToMove.RenderTransform
        Dim rectsMatrix As Matrix = rectTransform.Matrix
    
    
        ' Rotate the shape
        rectsMatrix.RotateAt(e.DeltaManipulation.Rotation,
                             e.ManipulationOrigin.X,
                             e.ManipulationOrigin.Y)
    
        ' Resize the Rectangle. Keep it square 
        ' so use only the X value of Scale.
        rectsMatrix.ScaleAt(e.DeltaManipulation.Scale.X,
                            e.DeltaManipulation.Scale.X,
                            e.ManipulationOrigin.X,
                            e.ManipulationOrigin.Y)
    
        'move the center
        rectsMatrix.Translate(e.DeltaManipulation.Translation.X,
                              e.DeltaManipulation.Translation.Y)
    
        ' Apply the changes to the Rectangle.
        rectTransform = New MatrixTransform(rectsMatrix)
        rectToMove.RenderTransform = rectTransform
    
        Dim container As FrameworkElement = e.ManipulationContainer
        Dim containingRect As New Rect(container.RenderSize)
    
        Dim shapeBounds As Rect = rectTransform.TransformBounds(
                                    New Rect(rectToMove.RenderSize))
    
        ' Check if the rectangle is completely in the window.
        ' If it is not and intertia is occuring, stop the manipulation.
        If e.IsInertial AndAlso Not containingRect.Contains(shapeBounds) Then
            e.Complete()
        End If
    
        e.Handled = True
    End Sub
    
    void Window_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
    {
    
        // Get the Rectangle and its RenderTransform matrix.
        Rectangle rectToMove = e.OriginalSource as Rectangle;
        Matrix rectsMatrix = ((MatrixTransform)rectToMove.RenderTransform).Matrix;
    
        // Rotate the Rectangle.
        rectsMatrix.RotateAt(e.DeltaManipulation.Rotation, 
                             e.ManipulationOrigin.X, 
                             e.ManipulationOrigin.Y);
    
        // Resize the Rectangle.  Keep it square 
        // so use only the X value of Scale.
        rectsMatrix.ScaleAt(e.DeltaManipulation.Scale.X, 
                            e.DeltaManipulation.Scale.X, 
                            e.ManipulationOrigin.X,
                            e.ManipulationOrigin.Y);
    
        // Move the Rectangle.
        rectsMatrix.Translate(e.DeltaManipulation.Translation.X,
                              e.DeltaManipulation.Translation.Y);
    
        // Apply the changes to the Rectangle.
        rectToMove.RenderTransform = new MatrixTransform(rectsMatrix);
    
        Rect containingRect =
            new Rect(((FrameworkElement)e.ManipulationContainer).RenderSize);
    
        Rect shapeBounds =
            rectToMove.RenderTransform.TransformBounds(
                new Rect(rectToMove.RenderSize));
    
        // Check if the rectangle is completely in the window.
        // If it is not and intertia is occuring, stop the manipulation.
        if (e.IsInertial && !containingRect.Contains(shapeBounds))
        {
            e.Complete();
        }
    
    
        e.Handled = true;
    }
    
  6. Nella classe MainWindow aggiungere il gestore eventi ManipulationInertiaStarting.

    L'evento ManipulationInertiaStarting si verifica quando l'utente solleva tutte le dita dallo schermo. Nel codice viene impostata la velocità iniziale e la decelerazione per il movimento, l'espansione e la rotazione del rettangolo.

    Private Sub Window_InertiaStarting(ByVal sender As Object,
                                       ByVal e As ManipulationInertiaStartingEventArgs)
    
        ' Decrease the velocity of the Rectangle's movement by 
        ' 10 inches per second every second.
        ' (10 inches * 96 pixels per inch / 1000ms^2)
        e.TranslationBehavior.DesiredDeceleration = 10.0 * 96.0 / (1000.0 * 1000.0)
    
        ' Decrease the velocity of the Rectangle's resizing by 
        ' 0.1 inches per second every second.
        ' (0.1 inches * 96 pixels per inch / (1000ms^2)
        e.ExpansionBehavior.DesiredDeceleration = 0.1 * 96 / (1000.0 * 1000.0)
    
        ' Decrease the velocity of the Rectangle's rotation rate by 
        ' 2 rotations per second every second.
        ' (2 * 360 degrees / (1000ms^2)
        e.RotationBehavior.DesiredDeceleration = 720 / (1000.0 * 1000.0)
    
        e.Handled = True
    End Sub
    
    void Window_InertiaStarting(object sender, ManipulationInertiaStartingEventArgs e)
    {
    
        // Decrease the velocity of the Rectangle's movement by 
        // 10 inches per second every second.
        // (10 inches * 96 pixels per inch / 1000ms^2)
        e.TranslationBehavior.DesiredDeceleration = 10.0 * 96.0 / (1000.0 * 1000.0);
    
        // Decrease the velocity of the Rectangle's resizing by 
        // 0.1 inches per second every second.
        // (0.1 inches * 96 pixels per inch / (1000ms^2)
        e.ExpansionBehavior.DesiredDeceleration = 0.1 * 96 / (1000.0 * 1000.0);
    
        // Decrease the velocity of the Rectangle's rotation rate by 
        // 2 rotations per second every second.
        // (2 * 360 degrees / (1000ms^2)
        e.RotationBehavior.DesiredDeceleration = 720 / (1000.0 * 1000.0);
    
        e.Handled = true;
    }
    
  7. Compilare ed eseguire il progetto.

    Nella finestra verrà visualizzato un quadrato di colore rosso.

Verifica dell'applicazione

Per testare l'applicazione, provare a eseguire le modifiche che seguono. Si noti che è possibile eseguire più modifiche contemporaneamente.

  • Per spostare Rectangle, posizionare un dito su Rectangle e spostare il dito sullo schermo.

  • Per ridimensionare Rectangle, posizionare due dita su Rectangle e aprire o chiudere le dita.

  • Per ruotare Rectangle, posizionare due dita su Rectangle e ruotare un dito intorno all'altro.

Per causa l'inerzia, sollevare velocemente le dita dallo schermo durante l'esecuzione delle modifiche precedenti. L'oggetto Rectangle continuerà a venire spostato, ridimensionato o ruotato per qualche secondo prima che si fermi.

Vedere anche

Riferimenti

UIElement.ManipulationStarting

UIElement.ManipulationDelta

UIElement.ManipulationInertiaStarting