Tutorial: Crear la primera aplicación táctil

WPF permite a las aplicaciones responder a la función táctil. Por ejemplo, puede interactuar con una aplicación mediante uno o varios dedos en un dispositivo táctil, como una pantalla táctil. En este tutorial se crea una aplicación que permite al usuario mover, cambiar el tamaño o girar un solo objeto mediante la función táctil.

Requisitos previos

Necesitará los componentes siguientes para completar este tutorial:

  • Visual Studio.

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

Además, debe tener conocimientos básicos sobre 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: Mi primera aplicación de escritorio WPF.

Crear la aplicación

Para crear la aplicación

  1. Cree un proyecto de aplicación de WPF en Visual Basic o Visual C# denominado BasicManipulation. Para obtener más información, vea Tutorial: Mi primera aplicación de escritorio WPF.

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

    Este marcado crea una aplicación sencilla que contiene un Rectangle de color rojo en Canvas. La propiedad IsManipulationEnabled de Rectangle se establece en True para que reciba eventos de manipulación. La aplicación se suscribe a los eventos ManipulationStarting, ManipulationDelta y ManipulationInertiaStarting. Estos eventos contienen la lógica para mover el objeto Rectangle cuando el usuario lo manipula.

    <Window x:Class="BasicManipulation.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://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" por x:Class="MainWindow".

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

    El evento ManipulationStarting se produce cuando WPF detecta que la entrada táctil comienza 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.

    void Window_ManipulationStarting(object sender, ManipulationStartingEventArgs e)
    {
        e.ManipulationContainer = this;
        e.Handled = true;
    }
    
    Private Sub Window_ManipulationStarting(ByVal sender As Object, ByVal e As ManipulationStartingEventArgs)
        e.ManipulationContainer = Me
        e.Handled = True
    End Sub
    
  5. En la clase MainWindow, agregue el siguiente controlador de eventos ManipulationDelta.

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

    El código aplica DeltaManipulation al 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 se produce el evento durante la inercia. Si es así, la aplicación llama al método ManipulationDeltaEventArgs.Complete para finalizar la manipulación.

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

    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, la expansión y el giro del rectángulo.

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

    Debería ver que aparece un cuadrado rojo en la ventana.

Probar la aplicación

Para probar la aplicación, pruebe las siguientes manipulaciones. Tenga en cuenta que puede hacer más de una de los siguientes al mismo tiempo.

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

  • Para cambiar el tamaño de Rectangle, coloque dos dedos en Rectangle y mueva los dedos acercándolos o separándolos.

  • Para girar Rectangle, coloque dos dedos en Rectangle y gire los dedos entre ellos.

Para provocar inercia, levante rápidamente los dedos de la pantalla mientras realiza las manipulaciones anteriores. Rectangle seguirá moviéndose, cambiando de tamaño o girando durante unos segundos antes de que se detenga.

Vea también