Windows Phone 7 – Tutorial XXII–Touch Input II

Después de dos semanas sin escribir nada debido a que hemos estado a tope con el trabajo, vamos a ver en este post parte de los eventos que vimos en el articulo anterior.

Tap

clip_image001

Este evento funciona como si tuviésemos un ratón en nuestro dedo y reacciona al simple toque de nuestro dedo en la pantalla, como supondréis este gesto viene implementado en muchos controles, por ejemplo el control Button lo expone a través del evento Click 

< Button Content=”Simple Gestures” Name=”SimpleGestureButton” Click=”SimpleGestureButton_Click” / >

Sin embargo no todos los controles exponen el gesto Tap, por ejemplo el elemento Border que hereda de Panel no expone el evento Click, si seguimos el árbol de herencia veremos que llegaremos al elemento UIElement el cual expone los eventos MouseLeftButtonDown y MouseLeftButtonUp . Para simular el gesto de Tap con estos dos eventos podríamos utilizar un behaivor que nos permita reusarlo para cualquier elemento.

Para realizar un behaivor podéis ver este articulo que aunque sea de WPF es lo mismo tanto para Silverlight como WPF, recordar que para realizar un behaivor debemos de añadir la referencia al assemblie System.Windows.Interactivity.dll, el behaivor lo enlazaremos a cualquier elemento de la clase UIElement y lo que hará será lanzar un evento Tap jugando con los dos eventos anteriores, aquí tenéis  el código.

1 public class TapAction : Behavior<UIElement> 2 { 3 public event EventHandler Tap; 4 5 protected bool MouseDown { get; set; } 6 7 protected override void OnAttached() 8 { 9 base.OnAttached(); 10 11 this.AssociatedObject.MouseLeftButtonDown += AO_MouseLeftButtonDown; 12 this.AssociatedObject.MouseLeftButtonUp += AO_MouseLeftButtonUp; 13 } 14 15 protected override void OnDetaching() 16 { 17 this.AssociatedObject.MouseLeftButtonDown -= AO_MouseLeftButtonDown; 18 this.AssociatedObject.MouseLeftButtonUp -= AO_MouseLeftButtonUp; 19 20 base.OnDetaching(); 21 } 22 23 void AO_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) 24 { 25 if (MouseDown) 26 { 27 OnTap(); 28 } 29 MouseDown = false; 30 } 31 32 void AO_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 33 { 34 MouseDown = true; 35 } 36 37 protected virtual void OnTap() 38 { 39 if (Tap != null) 40 { 41 Tap(this.AssociatedObject, EventArgs.Empty); 42 } 43 } 44 }

Luego en cualquier elemento como un Border se lo asociaremos por XAML

 

1 <phone:PhoneApplicationPage 2 x:Class="TouchInput.MainPage" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" 6 xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" 7 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 8 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 9 xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 10 xmlns:local="clr-namespace:TouchInput.Helper" 11 mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768" 12 FontFamily="{StaticResource PhoneFontFamilyNormal}" 13 FontSize="{StaticResource PhoneFontSizeNormal}" 14 Foreground="{StaticResource PhoneForegroundBrush}" 15 SupportedOrientations="Portrait" Orientation="Portrait" 16 shell:SystemTray.IsVisible="True"> 17 18 <!--LayoutRoot is the root grid where all page content is placed--> 19 <Grid x:Name="LayoutRoot" Background="Transparent"> 20 <Grid.RowDefinitions> 21 <RowDefinition Height="Auto"/> 22 <RowDefinition Height="*"/> 23 </Grid.RowDefinitions> 24 25 <!--TitlePanel contains the name of the application and page title--> 26 <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="24,24,0,12"> 27 <TextBlock x:Name="ApplicationTitle" Text="BUILT TO ROAM" Style="{StaticResource PhoneTextNormalStyle}"/> 28 <TextBlock x:Name="PageTitle" Text="flick tap pane" Margin="-3,-8,0,0" Style="{StaticResource PhoneTextTitle1Style}"/> 29 </StackPanel> 30 31 <!--ContentPanel - place additional content here--> 32 <Grid x:Name="ContentGrid" Grid.Row="1"> 33 <Border BorderBrush="#FFF11717" BorderThickness="2" Height="90" Margin="20,0,0,409" VerticalAlignment="Bottom" Background="#FFCC8787" HorizontalAlignment="Left" Width="160"> 34 <i:Interaction.Behaviors> 35 <local:TapAction Tap="TapGesture_Tap"/> 36 </i:Interaction.Behaviors> 37 </Border> 38 39 </Grid> 40 </Grid>

Para asociar el behaivor por Blend os dejo los siguientes pantallazos:

 

imageimageimage

 

Como podéis ver capturamos el evento Tap y en el code-behind

1 private void TapGesture_Tap(object sender, EventArgs e) 2 { 3 MessageBox.Show("Has hecho TAP en el Border!"); 4 }

De esta manera capturamos todos los eventos de Tap de una manera muy sencilla

 

Double Tap

clip_image002

 

Recordamos que el Double-Tap son dos gestos Tap en un periodo de tiempo muy corto, no existe este evento en ningún objeto con lo que aprovecharemos el behaivor anterior para extenderlo para detectar estos dos Tap, incluiremos una propiedad donde indicaremos el tiempo que queremos que pase entre gesto y gesto, a este behaivor le llamaremos DoubleTapAction, os dejo el código a continuación.

1 public class DoubleTapAction : TapAction 2 { 3 public event EventHandler DoubleTap; 4 5 public int DoubleTapTimeoutInMilliseconds 6 { 7 get { return (int)GetValue(DoubleTapTimeoutInMillisecondsProperty); } 8 set { SetValue(DoubleTapTimeoutInMillisecondsProperty, value); } 9 } 10 11 public static readonly DependencyProperty DoubleTapTimeoutInMillisecondsProperty = 12 DependencyProperty.Register("DoubleTapTimeoutInMilliseconds", typeof(int), 13 typeof(DoubleTapAction), new PropertyMetadata(1000)); 14 15 protected DateTime? FirstTap { get; set; } 16 17 protected override void OnTap() 18 { 19 base.OnTap(); 20 21 if (FirstTap.HasValue && 22 FirstTap.Value.AddMilliseconds(DoubleTapTimeoutInMilliseconds) > DateTime.Now) 23 { 24 OnDoubleTap(); 25 FirstTap = null; 26 } 27 else 28 { 29 FirstTap = DateTime.Now; 30 } 31 } 32 33 protected virtual void OnDoubleTap() 34 { 35 if (DoubleTap != null) 36 { 37 DoubleTap(this.AssociatedObject, EventArgs.Empty); 38 } 39 } 40 }

En el código anterior podéis ver que se ha definido la propiedad DoubleTapTimeoutInMilliseconds  que nos indicará el tiempo entre gestos Tap y se ha definido por defecto que sea de 1 segundo.

1 public class TapAction : Behavior<UIElement> 2 { 3 public event EventHandler Tap; 4 5 protected bool MouseDown { get; set; } 6 7 protected override void OnAttached() 8 { 9 base.OnAttached(); 10 11 this.AssociatedObject.MouseLeftButtonDown += AO_MouseLeftButtonDown; 12 this.AssociatedObject.MouseLeftButtonUp += AO_MouseLeftButtonUp; 13 } 14 15 protected override void OnDetaching() 16 { 17 this.AssociatedObject.MouseLeftButtonDown -= AO_MouseLeftButtonDown; 18 this.AssociatedObject.MouseLeftButtonUp -= AO_MouseLeftButtonUp; 19 20 base.OnDetaching(); 21 } 22 23 void AO_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) 24 { 25 if (MouseDown) 26 { 27 OnTap(); 28 } 29 MouseDown = false; 30 } 31 32 void AO_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 33 { 34 MouseDown = true; 35 } 36 37 protected virtual void OnTap() 38 { 39 if (Tap != null) 40 { 41 Tap(this.AssociatedObject, EventArgs.Empty); 42 } 43 } 44 }

El XAML del nuevo Border sería

 

1 <Border BorderBrush="#FFF11717" BorderThickness="2" Margin="0,118,21,0" Background="#FFCC8787" HorizontalAlignment="Right" Width="160" Height="90" VerticalAlignment="Top"> 2 <i:Interaction.Behaviors> 3 <local:DoubleTapAction DoubleTap="DoubleTapGesture_DoubleTap"/> 4 </i:Interaction.Behaviors> 5 </Border>

1 <Border BorderBrush="#FFF11717" BorderThickness="2" Margin="0,118,21,0" Background="#FFCC8787" HorizontalAlignment="Right" Width="160" Height="90" VerticalAlignment="Top"> 2 <i:Interaction.Behaviors> 3 <local:DoubleTapAction DoubleTap="DoubleTapGesture_DoubleTap"/> 4 </i:Interaction.Behaviors> 5 </Border>

1 private void DoubleTapGesture_DoubleTap(object sender, EventArgs e) 2 { 3 MessageBox.Show("Has hecho Doucble-Tap en el Border!"); 4 }

En este articulo hemos vistos los dos primeros gestos, en los siguientes iremos desmenuzando los gestos que nos quedan, os dejo el código del proyecto

Un comentario sobre “Windows Phone 7 – Tutorial XXII–Touch Input II”

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *