Tutorial: Crear su primera aplicación táctil

WPF permite que las aplicaciones respondan a la entrada táctil. Por ejemplo, puede interactuar con una aplicación usando uno o más dedos en un dispositivo sensible al tacto, como una pantalla táctil. Este tutorial crea una aplicación que permite al usuario mover, cambiar el tamaño o girar un único objeto utilizando una entrada táctil.

Requisitos previos

Necesita los componentes siguientes para completar este tutorial:

  • Microsoft Visual Studio 2010.

  • Windows 7.

  • Un dispositivo que acepte la entrada táctil, como una pantalla táctil, compatible con Windows Touch.

Además, debe tener conocimientos básicos de cómo crear una aplicación en WPF, especialmente cómo suscribirse a un evento y controlarlo. Para obtener más información, vea Tutorial: Introducción a WPF.

Crear la aplicación

Para crear la aplicación

  1. Cree un nuevo proyecto de aplicación de WPF en Visual Basic o en Visual C# denominado BasicManipulation. Para obtener más información, vea Cómo: Crear un nuevo proyecto de aplicación de WPF.

  2. Reemplace el contenido de MainWindow.xaml con el código XAML siguiente.

    Este marcado crea una aplicación sencilla que contiene un Rectangle rojo en un Canvas. La propiedad IsManipulationEnabled de Rectangle está establecida en true, por lo que recibirá los eventos de manipulación. La aplicación se suscribe a los eventos ManipulationStarting, ManipulationInertiaStarting y ManipulationDelta. Estos eventos contienen la lógica para mover Rectangle cuando el usuario lo manipule.

    <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. Si usa Visual Basic, en la primera línea de MainWindow.xaml, reemplace x:Class="BasicManipulation.MainWindow" con x:Class="MainWindow".

  4. En la clase MainWindow, agregue el controlador de eventos ManipulationStarting siguiente.

    El evento ManipulationStarting se produce cuando WPF detecta que la entrada táctil empieza a manipular un objeto. El código especifica que la posición de la manipulación debe ser relativa a Window estableciendo la propiedad 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. En la clase MainWindow, agregue el controlador de eventos ManipulationDelta siguiente.

    El evento ManipulationDelta se produce cuando la entrada táctil cambia de posición y puede producirse varias veces durante una manipulación. El evento también se puede producir después de que se haya levantado un dedo. Por ejemplo, si el usuario arrastra un dedo por una pantalla, el evento ManipulationDelta se produce varias veces a medida que el dedo se mueve. Cuando el usuario levanta un dedo de la pantalla, el evento ManipulationDelta sigue produciéndose para simular la inercia.

    El código aplica la propiedad DeltaManipulation a la propiedad RenderTransform de Rectangle para moverlo a medida que el usuario mueve la entrada táctil. También comprueba si Rectangle está fuera de los límites de Window cuando el evento se produce durante la inercia. Si lo está, la aplicación llama al método ManipulationDeltaEventArgs.Complete para finalizar la manipulación.

    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. En la clase MainWindow, agregue el controlador de eventos ManipulationInertiaStarting siguiente.

    El evento ManipulationInertiaStarting se produce cuando el usuario levanta todos los dedos de la pantalla. El código establece la velocidad inicial y la desaceleración para el movimiento, expansión y giro del rectángulo.

    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. Compile y ejecute el proyecto.

    Debe ver que aparece un cuadrado rojo en la ventana.

Probar la aplicación

Para probar la aplicación, intente realizar las manipulaciones siguientes: Tenga en cuenta que puede realizar más de una de las acciones siguientes al mismo tiempo.

  • Para mover Rectangle, ponga un dedo en Rectangle y mueva el dedo por la pantalla.

  • Para cambiar el tamaño de Rectangle, ponga dos dedos en Rectangle y acerque o aparte los dedos.

  • Para girar Rectangle, ponga dos dedos en Rectangle y gire los dedos uno alrededor del otro.

Para producir inercia, levante rápidamente los dedos de la pantalla mientras realiza las manipulaciones anteriores. Rectangle se seguirá moviendo, cambiando de tamaño o girando durante unos segundos antes de detenerse.

Vea también

Referencia

UIElement.ManipulationStarting

UIElement.ManipulationDelta

UIElement.ManipulationInertiaStarting