lördag 17 oktober 2009

Multi touch in WPF 4.0 and VS2010

Touch and multitouch is something that has been dear to my heart last year. It all started when Connecta bought a Microsoft Surface table for almost a year ago. Even then, Microsoft talked about the need to work with, and learn multi-touch, and now we see Windows 7 and WPF 4.0 come with native support for multi-touch.

WPF 4.0 has added a number of events to the UIElement that relates to muti touch. The .NET APIs are based on native Win32 APIs that are available only in Windows 7. UIElement is the base class that defines the essence of visual controls for layout, input and events. The events that exist today (Beta 1 of VS2010) are: ManipulationStarted Event,
ManipulationCompleted Event,
Manipulation Delta Event,
ManipulationInertiaStarting Event and ManipulationBoundaryFeedback Event.

By default, a UIElement never recieves events relating to manipulation unless Manipulation Mode is set to a value other than None. With the help of Manipulation mode you can control the type of manipulation you can make on an item. It can for instance be translated in X and/or Y axis, rotate, or scale.

In beta 1 of. NET Framework 4.0 the are events for manipulationare are there but there are not any WPF controls that make use of them. In future versions it will be easy just turn on the touch controls on eg sliders or scrollviewers directly in XAML.

When the ManipulationDelta event is captured in a Window you get a ManipulationDeltaEventArgs. That can be used to find out what changes have occurred on the item manipulated. With the method GetDeltaManipulation you get a System.Windows.Input.Manipulation which contains all of the transformation data that was available when the event occurred. The information can then be used to perform translatation operations on the object. A bit complex, but a piece of code probably makes it easier to understand!

Please note that the ManipulationDelta event will never fire with an ordinary mouse. There must be some kind of touch device. With the help of a project on CodePlex called Multi-Touch Vista you can simulate the use of multiple touch points with normal mouse or a touch pad.

In the XAML-file I add an Image to the Canvas. To that I connect a MatrixTransform so that I can access it from code. I also add an event handler for the ManipulationDelta.

<Window   x:Class="WpfApplication13.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
Title="Window1" Height="300" Width="300"
WindowState="Maximized" ManipulationDelta="Window_ManipulationDelta">
<MatrixTransform x:Key="InitialMatrixTransform">
<Matrix OffsetX="200" OffsetY="200"></Matrix>
<Image Width="100" Source="/WpfApplication13;component/Images/Sonicspree.jpg" ManipulationMode="All" RenderTransform="{StaticResource InitialMatrixTransform}" ></Image>

In the code behind I use DeltaManipulation to move the image based on input:

private void Window_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
var delta = e.GetDeltaManipulation(this);
var image = e.OriginalSource as Image;
var matrix = ((MatrixTransform)image.RenderTransform).Matrix;
var originalCenter = new Point(image.ActualWidth / 2, image.ActualHeight / 2);

//Translate on the x and y-axis
matrix.Translate(delta.Translation.X, delta.Translation.Y);

//Get the new center point and rotate around that based on the delta
var center = matrix.Transform(originalCenter);
matrix.RotateAt(delta.Rotation, center.X, center.Y);
center = matrix.Transform(originalCenter);

//Scale the matrix based on the delta
matrix.ScaleAt(delta.Scale, delta.Scale, center.X, center.Y);

//Apply the new MatrixTransform
image.RenderTransform = new MatrixTransform(matrix);

e.Handled = true;


Note the two red dots representing the two mice I have connected to this computer. The code in this example is based on a video on You Tube that also shows the application in action.



2 kommentarer:

  1. Hi I cant find the GetDeltaManipulation function. I get a compilation error:
    System.Windows.Input.ManipulationDeltaEventArgs does not contain a definition for GetDeltaManipulation and no extension method GetDeltaManipulation accepting a first argument of type System.Windows.Input.ManipulationDeltaEventArgs could be found (are you missing a using directive or an assembly reference?)

  2. Hi...
    Do you know how to limit the size of matrix?
    Can you please tech me?thank's