Multitouch i Windows 7 med Silverlight 3

En av de kanske minst kända nyheterna i Silverlight 3 är möjligheten att hantera input från multitouch-skärmar på datorer som kör Windows7. Det här öppnar upp för riktigt intressanta scenarion –  ett exempel är att kunna köra en webbaserad kampanj på sin sajt och sedan köra exakt samma applikation på multitouch-skärmar i en butiksmiljö.

För att kunna använda multitouch i Windows 7 med Silverlight krävs naturligtvis att du har tillgång till hårdvara med stöd för multitouch. Både HP och Dell har i dagsläget ett antal enheter med stöd för multitouch och fler är på väg. Jag har testat HP TouchSmart tx2 som är en trevlig och behändig liten laptop, den är faktiskt inte speciellt dyr heller.

I Silverlight får du inte tillgång till alla multitouch-meddelanden som Windows levererar när operativsystemet känner igen olika gester (t.ex. att dra isär fingrarna för zoom-gest) utan endast basala ‘TouchPoints’-event som innehåller information om vilken typ av meddelande (TOUCHEVENTF_DOWN, TOUCHEVENTF_MOVE, TOUCHEVENTF_UP) samt vilken position på skärmen som eventet rör.

För att hantera multitouch i Silverlight 3 så använder du den nya statiska klassen ‘Touch’ och dess ‘FrameReported’-event:

  
         Touch.FrameReported+=new TouchFrameEventHandler(Touch_FrameReported);

Till skillnad från t.ex. MouseOver-event så kan inte FrameReported kopplas till enskilda element eller kontroller i Silverlight-applikationen utan gäller för hela applikationen.

Som argument till FrameReported -eventet kommer du att få ett antal TouchPoints. Varje TouchPoint kan ha en ‘Action’ som är antingen Down, Move eller Up. Down sker när ett finger sätts på skärmen. Därefter kommer Windows kontinuerligt att skicka Move-meddelanden tills fingret lyfts och ett Up-meddelande sänds.

För att hantera dessa meddelanden så loopar du igenom TouchPoints och undersöker varje Points action. Så här kan det se ut ifall man skriver en anonym metod i C# för att hantera eventet:

  
             Touch.FrameReported += (s, e) =>
             {
  
                 foreach (TouchPoint tp in e.GetTouchPoints(null))
                 {
                     switch (tp.Action)
                     {
                         case TouchAction.Down:
                             {
                                 //TODO hantera att användaren startat gest
                                 break;
  
                             }
                         case TouchAction.Move:
                             {
                                 //TODO hantera att användaren rör fingret
                                 break;
                             }
                         case TouchAction.Up:
                             {
                                 //TODO hantera att användaren släpper skärmen
                                 break;
                             }
                     }
                 }

 

Varje TouchPoint innehåller sedan information som du kan använda dig av för att t.ex. flytta ett objekt eller skala om det. Via Position.X och Position.Y kan du få ut koordinaterna från eventet och via TouchDevice.DirectlyOver får du det element som ligger överst där touch-eventet skedde:

 case TouchAction.Move:
     {
         //TODO hantera att användaren rör fingret
  
         // PositionX och PositionY innehåller
         // de nya x,y koordinaterna:
         double positionX = tp.Position.X;
         double positionY = tp.Position.Y;
  
         // TouchDevice.DirectlyOver innehåller
         // vilket element som ligger överst där
         // touch eventet skedde
         UIElement el = tp.TouchDevice.DirectlyOver;

 

Nu är ju det här ett ganska ‘rått’ sätt att komma åt och tolka användargester på – och det krävs en hel del kodning för att kunna läsa av t.ex. en zoomningsgest utförd med två fingrar. Men som tur är börjar det redan poppa upp intressanta community-projekt som utökar touch-funktionaliteten i Silverlight:

  • Davide Zordan har skapat Behaviors som du direkt kan koppla på kontroller och element i Expression Blend 3 för att få ‘Drag’ och ‘Zoom’-funktionalitet

  • MIRIA SDK innehåller en uppsättning gestbaserade User Controls och har en egen “gest-tolkare” som kan känna igen gester och spåra hur fingrar används