Windows 7 Multi-touch Panning with ScrollViewer in WPF 3.5 Part Duex

In my last post I described a class that wraps the ScrollViewer control to enable multi-touch panning in it.

Well, it’s not exactly the right way to do it. You should be receiving the pan messages in the Window, then finding the scroll viewer where the window was touched using a Hit Test, and scroll that ScrollViewer.

 

Code Snippet
  1.         private void Page2_Loaded(object sender, RoutedEventArgs e)
  2.         {
  3.             // Get our items for the itemscontrols
  4.             this.GetItems();
  5.  
  6.             // Check for multi-touch capabilities
  7.             if (Windows7.Multitouch.Handler.DigitizerCapabilities.IsMultiTouchReady)
  8.             {
  9.                 // Enable stylus events
  10.                 Windows7.Multitouch.WPF.Factory.EnableStylusEvents(this);
  11.                 // Add the gesture handler
  12.                 this.GestureHandler = Windows7.Multitouch.WPF.Factory.CreateGestureHandler(Window.GetWindow(this));
  13.                 // Attach the handler to the method
  14.                 this.GestureHandler.Pan += new EventHandler<Windows7.Multitouch.GestureEventArgs>(this.GestureHandler_Pan);
  15.             }
  16.         }
  17.  
  18.  
  19.         private void GestureHandler_Pan(object sender, Windows7.Multitouch.GestureEventArgs e)
  20.         {
  21.             this.panTranslation = e.PanTranslation;
  22.  
  23.             PointHitTestParameters hitTestParameters = new PointHitTestParameters(Windows7.Multitouch.WPF.PointUtil.ToDrawingPointF(e.Center));
  24.             VisualTreeHelper.HitTest(this, null, new HitTestResultCallback(this.HitTestResult), hitTestParameters);
  25.         }
  26.  
  27.         public HitTestResultBehavior HitTestResult(HitTestResult rawresult)
  28.         {
  29.             ScrollViewer sv = null;
  30.             try
  31.             {
  32.                 sv = (ScrollViewer)rawresult.VisualHit;
  33.             }
  34.             catch
  35.             {
  36.             }
  37.  
  38.             // If we have a reference to the scrollviewer, then we scroll
  39.             if (sv != null)
  40.             {
  41.                 // Make the Scroller scroll
  42.                 sv.ScrollToVerticalOffset(sv.VerticalOffset - this.panTranslation.Height);
  43.  
  44.                 // Stop trying to find more controls in the visual tree
  45.                 return HitTestResultBehavior.Stop;
  46.  
  47.             }
  48.             else
  49.             {
  50.                 // Continue trying to find more controls in the visual tree
  51.                 return HitTestResultBehavior.Continue;
  52.             }
  53.  
  54.         }

When you are tracking multi-touch in a specific control, the touchs register at the window level, so even if you are not touching in the ScrollViewer, it still will pan it.

So the code was moved to the window , and uses the standard <ScrollViewer>.

Download the example project in C# and VB.NET

13. November 2009 01:23 by Rick | Comments (2) | Permalink

Windows 7 Multi-touch Panning with ScrollViewer in WPF 3.5

UPDATE: You should be using the Window to receive events. See my updated post for details.

Yes, it can be done easily, including inertia. It does require the Windows 7 Multitouch .NET Interop Sample Library

First, create a class that inherits from scrollviewer.

Code Snippet
  1. Public Class MultiTouchScollViewer
  2.     Inherits ScrollViewer
  3.  
  4. End Class

Then you add references to Windows7.Multitouch.dll and Windows7.Multitouch.Wpf.dll.

Then modify the MultiTouchScrollViewer like so:

Code Snippet
  1. Imports System.Windows
  2. Imports System.Windows.Controls
  3.  
  4. Public Class MultiTouchScrollViewer
  5.     Inherits ScrollViewer
  6.  
  7.     Private GestureHandler As Windows7.Multitouch.GestureHandler
  8.  
  9.     Public Sub New()
  10.         AddHandler MyBase.Loaded, New RoutedEventHandler(AddressOf Me.MultiTouchScollViewer_Loaded)
  11.         Me.GestureHandler = Nothing
  12.     End Sub
  13.  
  14.     Private Sub MultiTouchScollViewer_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs)
  15.         If Windows7.Multitouch.TouchHandler.DigitizerCapabilities.IsMultiTouchReady Then
  16.             GestureHandler = Windows7.Multitouch.WPF.Factory.CreateGestureHandler(System.Windows.Window.GetWindow(Me))
  17.             AddHandler GestureHandler.Pan, AddressOf Me.GestureHandler_Pan
  18.         End If
  19.     End Sub
  20.  
  21.     Private Sub GestureHandler_Pan(ByVal sender As Object, ByVal e As Windows7.Multitouch.GestureEventArgs)
  22.         Dim s As System.Drawing.Size = e.PanTranslation
  23.  
  24.         Me.ScrollToVerticalOffset(Me.VerticalOffset - s.Height)
  25.     End Sub
  26.  
  27. End Class

Download the VB.NET code here

Download the C# code here

NOTE: It does require hit testing if using multiple scrollviewers in the same window.

9. November 2009 05:04 by Rick | Comments (2) | Permalink

About Rick

Rick lives in North Las Vegas. He loves his wife, kids, dog, motorcycle, music and programming. There ain't nothing else. Oh yeah, mountain dew!



Programming interests are geared towards multimedia. Platforms are asp.net, windows forms, and WPF.

Calendar

<<  March 2010  >>
MoTuWeThFrSaSu
22232425262728
1234567
891011121314
15161718192021
22232425262728
2930311234

View posts in large calendar

RecentComments

Comment RSS