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