I have been writing applications for the Surface recently and started to experiment integrating Behaviors into my applications. One behavior that I am using is a conversion from Laurent Bugnion and his amazing Zoom Behavior for WPF. It was very straight forward and simple to convert this to a Surface Behavior and I would like to demonstrate how I accomplished that in this post.
First thing, go grab Laurent's excellent Zoom Behavior source code (under the Downloads section). Then create a new Surface application and copy in the three files for the Zoom Behavior: ZoomAdorner.cs, ZoomBehavior.cs and ZoomExtension.cs. The main thing we need to replace in the WPF Zoom Behavior code is the mouse events since Surface has no concept of a mouse, instead Surface understands Contact points (sorry, the Surface SDK is not open to the public just yet). These Contacts are how the Surface knows when there is some sort of user input and this is how we will tell the Zoom Behavior where to magnify.
The bulk of the work will be done in the ZoomAdorner class. There were only 3 things we had to change:
- Replace the MouseMove event with an appropriate Contact event
- Use the Contact event to hold onto the current position
- Update the SetGlass() method to reflect the new position from the Contact event
Pretty easy, right? But there are 2 more classes to deal with: ZoomBehavior.cs and ZoomExtension.cs. Lucky for us, neither class needs to be changed, but we will remove 2 lines from ZoomBehavior.cs that changes the cursor of the mouse when the Zoom Behavior is active since Surface does not deal with the Mouse. And that's it!
I have 2 attachments, one that is a direct port of Laurent's sample application that is Surface ready and another test application that uses a ScatterView to demonstrate that the Surface Zoom Behavior will work alongside the user and not interfere with dragging / dropping of Surface elements. Enjoy!
One thing to note, when testing this Zoom Behavior out I found a slight bug in the code. If you set the IsVisible property of the Zoom Behavior to True it will crash. Looking into this does not reveal exactly why this happens other than a private member is not set for some reason which ultimately causes this crash. To get around this, set the IsVisible property to false (or do not specify the property since it defaults to false) and in the code behind in the OnApplicationActivated(object sender, EventArgs e) method set the property to true. This will allow you to have the Zoom Behavior start when your application starts.
There can be a couple of improvements that can be made that would enhance this Zoom Behavior:
- Have multiple instances for multiple Contacts
- Demo of a new template with a slider to control the Zoom Factor
- Fix the IsVisible="True" at startup bug
One last thing to remember, if you are using the Surface Simulator then you need to run that first before running an application with this Zoom Behavior.