WP7 Gesture Recognizer and Behavior / Triggers

Posted by: Clarity Blogs: ASP.NET, on 19 Jul 2010 | View original | Bookmarked: 0 time(s)

Here is a quick gesture recognizer I wrote for the Windows Phone 7.  You can use the gesture recognizer standalone in code and attach to a UI element or you can also use the behavior + trigger.  The behavior attaches the gesture recognizer to a UI element and then you can add triggers for specific gesture events like Tap, DoubleTap, etc.

Here is a copy of the code.

   1:  <Grid x:Name="ContentGrid" Grid.Row="1" Background="#FF1F1f1F" Opacity=".1">
   2:      <i:Interaction.Behaviors>
   3:          <ci:GestureBehavior EnableDebugMode="True" />
   4:      </i:Interaction.Behaviors>
   5:      <i:Interaction.Triggers>
   6:          <ci:GestureTrigger Gesture="Tap">
   7:              <cmd:EventToCommand Command="{Binding GestureRecognizedCommand}" PassEventArgsToCommand="True" />
   8:          </ci:GestureTrigger>
   9:          <ci:GestureTrigger Gesture="DoubleTap">
  10:              <cmd:EventToCommand Command="{Binding GestureRecognizedCommand}" PassEventArgsToCommand="True" />
  11:          </ci:GestureTrigger>
  12:          <ci:GestureTrigger Gesture="TapAndHold">
  13:              <cmd:EventToCommand Command="{Binding GestureRecognizedCommand}" PassEventArgsToCommand="True" />
  14:          </ci:GestureTrigger>
  15:          <ci:GestureTrigger Gesture="Flick">
  16:              <cmd:EventToCommand Command="{Binding GestureRecognizedCommand}" PassEventArgsToCommand="True" />
  17:          </ci:GestureTrigger>
  18:          <ci:GestureTrigger Gesture="TwoFingerTap">
  19:              <cmd:EventToCommand Command="{Binding GestureRecognizedCommand}" PassEventArgsToCommand="True" />
  20:          </ci:GestureTrigger>
  21:          <ci:GestureTrigger Gesture="Shape">
  22:              <cmd:EventToCommand Command="{Binding GestureRecognizedCommand}" PassEventArgsToCommand="True" />
  23:          </ci:GestureTrigger>
  24:          <ci:GestureTrigger Gesture="PressAndTap">
  25:              <cmd:EventToCommand Command="{Binding GestureRecognizedCommand}" PassEventArgsToCommand="True" />
  26:          </ci:GestureTrigger>
  27:          <ci:GestureTrigger Gesture="TwoFingerDoubleTap">
  28:              <cmd:EventToCommand Command="{Binding GestureRecognizedCommand}" PassEventArgsToCommand="True" />
  29:          </ci:GestureTrigger>
  30:          <ci:GestureTrigger Gesture="TwoFingerTapAndHold">
  31:              <cmd:EventToCommand Command="{Binding GestureRecognizedCommand}" PassEventArgsToCommand="True" />
  32:          </ci:GestureTrigger>
  33:          <!--<ci:GestureTrigger Gesture="Scale">
  34:              <cmd:EventToCommand Command="{Binding GestureRecognizedCommand}" PassEventArgsToCommand="True" />
  35:          </ci:GestureTrigger>
  36:          <ci:GestureTrigger Gesture="Rotate">
  37:              <cmd:EventToCommand Command="{Binding GestureRecognizedCommand}" PassEventArgsToCommand="True" />
  38:          </ci:GestureTrigger>
  39:          <ci:GestureTrigger Gesture="Pan">
  40:              <cmd:EventToCommand Command="{Binding GestureRecognizedCommand}" PassEventArgsToCommand="True" />
  41:          </ci:GestureTrigger>-->
  42:      </i:Interaction.Triggers>
  43:  </Grid>
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

I used MVVMlight in the sample to demonstrate how you can use the behavior/trigger to declare all the gestures in XAML without needed to wire up specific event handlers.  Initially I tried putting the triggers collection inside the behavior, but many existing trigger actions dont work because they try to attach to the actual UI element and fail if they are declared inside the behavior.  The gesture trigger action looks for the gesture behavior attached to the element so there is only one gesture interpreter per element. Therefore you need the behavior on the element and a trigger for each gesture you want to handle.

The complete list of gestures recognized right now are:

TapAndHold, (pressing and holding on an element for almost a second without lifting your finger)
PressAndTap, (press on an element and hold that finger while tapping with a second finger)

To use some like rotate, press and tap or any of the other two finger gestures youll need a touchscreen or actual phone.  I havent use this in a real apps yet and it needs some more testing, but I think its a good start.  Performance in the emulator varies on the quality of your touchscreen, but it seems to work really well on an actual phone.  The Shape gesture is based on the $1 gesture recognizer at http://depts.washington.edu/aimgroup/proj/dollar/  I adapted the code to work on WP7.  Right now it just recognizes circle, rectangle, pigtail, check and question mark. You can use the sample app on that page to generate xml files to load any new / other shape gestures; there are already a bunch more included but the code needs to be altered to raise the events. Im not sure how useful some of the shape gestures are but it seemed cool if you could recognize a question mark and pop up a help menu or use a lasso gesture to select multiple items. The scale/rotate/flick/pan gestures just return some arguments that can be used by some other code to actually manipulate the items.  Laurent Bugnion has a nice behavior specifically for manipulating items - http://geekswithblogs.net/lbugnion/archive/2010/07/12/multitouch-behavior-update-for-windows-phone-7-tools-beta.aspx  This code is more focused on determing the actual gesture performed like pan vs flick or tap vs tap & hold.

Feel free to take any pieces of the code if its helpful to use in your own stuff. At some point it would be nice if the actual events were just built into items since the UI guidelines for the phone specifically mention some of these like tap and hold, double tap.  Seems less efficient if everyone has to write their own code for taphold or doubel tap and the timings arent consistent between applications.

Also here is a video of a demo - http://dl.dropbox.com/u/254416/gestures.mp4  It isnt that exciting and you most likely need to just try it out instead.

Category: C# | Other Posts: View all posts by this blogger | Report as irrelevant | View bloggers stats | Views: 4969 | Hits: 20

Similar Posts

  • Host WPF Controls in Windows Forms more
  • More WPFE, Virtual Earth, and AJAX goodness! more
  • WPF/E and Script# more
  • You gotta love SeeWindowsVista more

News Categories

.NET | Agile | Ajax | Architecture | ASP.NET | BizTalk | C# | Certification | Data | DataGrid | DataSet | Debugger | DotNetNuke | Events | GridView | IIS | Indigo | JavaScript | Mobile | Mono | Patterns and Practices | Performance | Podcast | Refactor | Regex | Security | Sharepoint | Silverlight | Smart Client Applications | Software | SQL | VB.NET | Visual Studio | W3 | WCF | WinFx | WPF | WSE | XAML | XLinq | XML | XSD