WPF - Multi Touch

O Windows 7 e suas versões superiores têm a capacidade de receber entrada de vários dispositivos sensíveis ao toque. Os aplicativos WPF também podem manipular a entrada de toque como outra entrada, como o mouse ou teclado, gerando eventos quando ocorre um toque.

O WPF expõe dois tipos de eventos quando ocorre um toque - touch events e manipulation events. Os eventos de toque fornecem dados brutos sobre cada dedo em uma tela sensível ao toque e seu movimento. Os eventos de manipulação interpretam a entrada como certas ações. Ambos os tipos de eventos são discutidos nesta seção.

Os seguintes componentes são necessários para desenvolver um aplicativo que responda ao toque.

  • Microsoft Visual Studio 2010 ou versões posteriores.
  • Windows 7 ou versão superior.
  • Um dispositivo, como uma tela sensível ao toque, compatível com o Windows Touch.

Os termos a seguir são comumente usados ​​quando a entrada de toque é discutida -

  • Touch- Tipo de entrada do usuário que pode ser reconhecido no Windows 7 ou posterior. A entrada de toque é iniciada a partir de uma tela sensível ao toque.

  • Multi Touch- Tipo de entrada que ocorre em mais de um ponto simultaneamente. No WPF, quando o toque é discutido, geralmente significa multitoque.

  • Manipulation- Ocorre quando o toque é inferido como uma ação física aplicada a um objeto. No WPF, os eventos de manipulação interpretam a entrada como uma tradução, expansão ou manipulação de rotação.

  • Touch Device - Representa um dispositivo que produz entrada de toque, como um único dedo em uma tela sensível ao toque.

Exemplo

Para entender todos esses conceitos, vamos criar um novo projeto WPF com o nome WPFTouchInput.

  • Arraste um retângulo de uma caixa de ferramentas para a janela de design e preencha o retângulo com uma imagem ou qualquer cor. Se quiser usar uma imagem, não se esqueça de incluí-la em sua solução, caso contrário o programa não será executado.

  • O código XAML a seguir inicializa um retângulo com diferentes propriedades e 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>

Aqui está a implementação para diferentes eventos de manipulação -

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; 
      } 
		
   } 
}

Quando você compila e executa o código acima, ele produzirá o seguinte widget.

Agora você pode girar, ampliar ou reduzir esta imagem com o dedo na tela de toque.