WPF: multitáctil
Windows 7 y sus versiones superiores tienen la capacidad de recibir información de varios dispositivos sensibles al tacto. Las aplicaciones WPF también pueden manejar la entrada táctil como otra entrada, como el mouse o el teclado, generando eventos cuando ocurre un toque.
WPF expone dos tipos de eventos cuando se produce un toque: touch events y manipulation events. Los eventos táctiles proporcionan datos sin procesar sobre cada dedo en una pantalla táctil y su movimiento. Los eventos de manipulación interpretan la entrada como ciertas acciones. Ambos tipos de eventos se tratan en esta sección.
Los siguientes componentes son necesarios para desarrollar una aplicación que pueda responder al tacto.
- Microsoft Visual Studio 2010 o versiones posteriores.
- Windows 7 o una versión superior.
- Un dispositivo, como una pantalla táctil, que admita Windows Touch.
Los siguientes términos se usan comúnmente cuando se habla de la entrada táctil:
Touch- Tipo de entrada de usuario que se puede reconocer en Windows 7 o posterior. La entrada táctil se inicia desde una pantalla sensible al tacto.
Multi Touch- Tipo de entrada que se produce desde más de un punto simultáneamente. En WPF, cuando se habla del tacto, generalmente significa multitáctil.
Manipulation- Ocurre cuando el tacto se infiere como una acción física que se aplica a un objeto. En WPF, los eventos de manipulación interpretan la entrada como una manipulación de traslación, expansión o rotación.
Touch Device - Representa un dispositivo que produce entrada táctil, como un solo dedo en una pantalla táctil.
Ejemplo
Para comprender todos estos conceptos, creemos un nuevo proyecto de WPF con el nombre WPFTouchInput.
Arrastre un rectángulo desde una caja de herramientas a la ventana de diseño y llene el rectángulo con una imagen o cualquier color. Si desea utilizar una imagen, no olvide incluir la imagen en su solución, de lo contrario, el programa no se ejecutará.
El siguiente código XAML inicializa un rectángulo con diferentes propiedades y eventos.
<Window x:Class = "WPFMultiTouchInput.MainWindow"
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"
xmlns:local = "clr-namespace:WPFMultiTouchInput"
mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604">
<Window.Resources>
<MatrixTransform x:Key = "InitialMatrixTransform">
<MatrixTransform.Matrix>
<Matrix OffsetX = "200" OffsetY = "200"/>
</MatrixTransform.Matrix>
</MatrixTransform>
</Window.Resources>
<Canvas>
<Rectangle Name = "manRect" Width = "321" Height = "241"
RenderTransform = "{StaticResource InitialMatrixTransform}"
IsManipulationEnabled = "true" Canvas.Left = "-70" Canvas.Top = "-170">
<Rectangle.Fill>
<ImageBrush ImageSource = "Images/DSC_0076.JPG"/>
</Rectangle.Fill>
</Rectangle>
</Canvas>
</Window>
Aquí está la implementación para diferentes eventos de manipulación:
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
namespace WPFMultiTouchInput {
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
}
void Window_ManipulationStarting(object sender, ManipulationStartingEventArgs e) {
e.ManipulationContainer = this;
e.Handled = true;
}
void Window_ManipulationDelta(object sender, ManipulationDeltaEventArgs e) {
Rectangle rectToMove = e.OriginalSource as Rectangle;
Matrix rectsMatrix = ((MatrixTransform)rectToMove.RenderTransform).Matrix;
rectsMatrix.RotateAt(e.DeltaManipulation.Rotation, e.ManipulationOrigin.X, e.ManipulationOrigin.Y);
rectsMatrix.ScaleAt(e.DeltaManipulation.Scale.X, e.DeltaManipulation.Scale.X,
e.ManipulationOrigin.X, e.ManipulationOrigin.Y);
rectsMatrix.Translate(e.DeltaManipulation.Translation.X,
e.DeltaManipulation.Translation.Y);
rectToMove.RenderTransform = new MatrixTransform(rectsMatrix);
Rect containingRect = new Rect(((FrameworkElement)e.ManipulationContainer).RenderSize);
Rect shapeBounds = rectToMove.RenderTransform.TransformBounds(new Rect(rectToMove.RenderSize));
if (e.IsInertial && !containingRect.Contains(shapeBounds)) {
e.Complete();
}
e.Handled = true;
}
void Window_InertiaStarting(object sender, ManipulationInertiaStartingEventArgs e) {
e.TranslationBehavior.DesiredDeceleration = 10.0 * 96.0 / (1000.0 * 1000.0);
e.ExpansionBehavior.DesiredDeceleration = 0.1 * 96 / (1000.0 * 1000.0);
e.RotationBehavior.DesiredDeceleration = 720 / (1000.0 * 1000.0);
e.Handled = true;
}
}
}
Cuando compile y ejecute el código anterior, producirá el siguiente widnow.
Ahora puede rotar, acercar, alejar esta imagen con el dedo en la pantalla táctil.