Mobile Zone is brought to you in partnership with:

Jerry Nixon is the Microsoft Developer Evangelist in Colorado. He has scary knowledge about Architecture, XAML, and SQL Server. He has terrifying knowledge about Windows Phone, the Kinect, and C#. And, he has simply ridiculous knowledge on Windows Desktop development in Windows 8. Jerry is a DZone MVB and is not an employee of DZone and has posted 104 posts at DZone. You can read more from them at their website. View Full User Profile

Give Your Windows Phone App the Finger!

02.09.2012
| 2061 views |
  • submit to reddit

My colleague Developer Evangelist, Sam Stokes, in California has written a compelling article on dragging items in Windows Phone.

But I have a problem with Sam’s approach

Maybe it’s because I have a problem with Sam – but probably not; he’s actually one of my top 90,000 people @ Microsoft. So, let’s talk about moving things in XAML!

Sam moves objects around by incrementing and decrementing an item’s top/left dependency property inside a Canvas.

Like this:

image


In the code above, Sam is using the ManipuationDelta event. This awesome event allows an individual UI element to track the movement of finger gestures on it. It simplifies the typical events that have to handle and track.

MSDN: The ManipulationDelta event occurs multiple times when the user drags fingers over the screen during a manipulation and again when inertia occurs. You can use the IsInertial property to check whether the event is occurring during inertia.


The element on with ManipulationDelta event occurs is not affected in any way when the event occurs. You must provide the logic to the element that is to be manipulated. The CumulativeManipulation and DeltaManipulation properties, which are of type ManipulationDelta, contain data about how the position of the manipulations change and interpreted as moving, resizing, or rotating an object. You apply that information to the element that is to be manipulated.


But there’s more to that code. Sam might be using the coolest event, but how is he relocating the ellipse? He’s incrementing and decrementing the Canvas.Top and Left dependency properties. When he does this, the ellipse appears to move and track the finger on the touch panel.

What’s the problem?

The problem is deep. And I have to start by saying that Sam’s approach is not necessarily wrong. There could be situations where position inside a canvas is the best choice. However, let’s talk about the downsides:

Canvas or Grid?

Changing the top/left of a child element will give the impression that it is moving. But inside a grid you need to change the margin. If you want to move two items you need to factor in the distance between them. What’s the problem? Well, should you use canvas or grid or something else? It simply means this approach is a potentially inconsistent approach.

Who’s your Neighbor

Changing the top/left of a child element will give the impression that it is moving. Any peer elements whose layout is bound to the location of the moving object must be redrawn with ever value change. What’s the problem? Well, do you really know every potentially related element? It simply means this approach is a potentially expensive approach.

GPU Acceleration

Transforms are a regimented approach to altering an element, even moving it. Hardware acceleration can be attached to consistent, regimented approaches. What’s the problem? How can the GPU understand why you are changing a dependency property’s value? It can’t. It simply means this approach cannot take advantage of GPU hardware acceleration.

Is there an alternative?

Yes. It’s TranslateTransform – a Silverlight class specifically designed to accommodate the task of moving objects from one position to another. (TranslateTransform is also part of WPF). And get this, even in the documentation dips into this discussion:

MSDN: The local 0,0 for an object can be offset on a Canvas using Canvas.Left and Canvas.Top, but this does not count as a transform; the object retains its own local 0,0 in this case for transform purposes.


A TranslateTransform is easy to use. A TranslateTransform has an X and Y property which correlate to the relative position to the element’s original layout location. As you would expect, negative numbers move it in a reverse direction.

Apply a TranslateTransform like this:image


And implement it like this:

image


In the code above, I handle the ManipulationDelta event to track the touch gestures by the user. In the handler, I increment and decrement the X and Y values of the TranslateTransform – just like Sam. And just like Sam, my object tracks (or moves) with the user’s finger. But unlike Sam, my approach is hardware accelerated and a common, repeatable pattern.

Conclusion

Admittedly, I am sort of picking on my colleague to make a point. The reality is, Sam’s approach works. In fact, it is a very common approach to moving elements in a XAML environment, but there are downsides – do those downsides really matter? Maybe not enough for you to rewrite your application, but then again maybe so.

You’re the developer, you need to make the final call. Now you have a little more information. Informed decisions are usually better decisions. But I can’t tell you what is right for your application. What I can tell you is that TranslateTransform is easy to use, powerful, high performing, and a consistent approach. Other than that, it’s up to you.

Special acknowledgement to Sam Stokes for starting a great discussion.

Best of luck!


Source: http://blog.jerrynixon.com/2012/02/mango-sample-give-your-app-finger.html

Published at DZone with permission of Jerry Nixon, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Paul Shezier replied on Fri, 2012/04/13 - 3:18pm

Well, I had an app that was moving 200 objects, and rewrote it to use this method, but I'm not sure I can tell the difference. 

Shouse I see any visual difference between the two implementations using the HostSettings below?
// Display the current frame rate counters.
Application.Current.Host.Settings.EnableFrameRateCounter = true;
// Show the areas of the app that are being redrawn in each frame.
Application.Current.Host.Settings.EnableRedrawRegions = true;
// Enable non-production analysis visualization mode,
// which shows areas of a page that are being GPU accelerated with a colored overlay.
Application.Current.Host.Settings.EnableCacheVisualization = true;

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.