Microsoft’s Silverlight 3 and the DeepZoom composer allow users to display high-resolution images interactively. This provides several benefits for either sets of images in a gallery or for smoothly viewing very large image files.
This brief tutorial will demonstrate how to set up a Silverlight 3 project with interactive zoom and panning/scrolling with a DeepZoom image.
The first thing we will do is add the MultiScaleImage control to our automatically generated UserControl. This control contains the event handlers that we will need to interact with the deep zoom image.
We’ve already added several event handlers to the control:
- MouseWheel: Event fires when the scroll wheel moves forward/backward on the mouse.
- MouseLeftButtonDown/Up: These events fire when the user clicks. Both will be necessary to determine if the user is clicking or dragging the image.
- MouseMove: Will also be used for dragging/panning the image within the control.
- MouseLeave: Indicates when the mouse cursor leaves the control area. Needed in case the user passes the edge of the control when panning.
Now that we have our control created within our XAML file, we can begin loading our images and adding the code to interact with the control. First, we need to prepare a DeepZoom image using the DeepZoom composer. There is a short video to learn how to import images and create a Silverlight DeepZoom collection. Once created, the “GeneratedImages” folder can be uploaded to a webserver of your choice, or used locally depending on the setup of your Silverlight project (be careful for cross-zone policy issues if debugging Silverlight from the ASP webserver and using local image files).
We will need three global variables to keep the status of our mouse:
We can then add in our basic information into the main constructor:
The above URL can point either to the collage “dzc_output.xml” file, or to an individual deep zoom image XML file (found in the “dzc_output_images” folder). This set of code will load the image into our control as soon as the form loads. Depending on how your application functions, this can be done at any point or bound to other controls (buttons, list of albums, etc).
The application should compile at this point and be able to display the images. Now we can start to add some interactivity to the images.
First, we will add the code to tell our control when the user is dragging the image:
The first value within “ZoomAboutLogicalPoint” can be adjusted based on how far in or out you would like the image to zoom. The additional values indicate the “LogicalPoint” within the image that was clicked (a value of 0 to 1 indicating the far left/top to far right/bottom). To prevent some general bugginess within the application, we’ll also add a “stop dragging” command for when the user leaves the control:
Now to actually handle the dragging. These statements get placed in the MouseMove event handler. If our user has clicked (_dragging == true), we can move the image. If our user hasn’t clicked, set the last position for use with dragging:
In the above code, the X and Y scroll distance is calculated by subtracting the current mouse position from the last recorded location. This value is then divided by the image’s ActualWidth and multiplied by the ViewportWidth to compensate for any zooming within the image (otherwise the image will scroll very fast or very slow if the user has zoomed in or out).
Almost done! We’re also going to add an event so that the use can scroll in and out using their mouse wheel:
We use our Delta value to determine if the user was scrolling in or out, and then zoom using ZoomAboutLogicalPoint accordingly. Again, the first value can be changed to alter the “speed” of zooming. This works great for desktop users, but adding additional functionality for people without scroll wheels (particularly laptop users) would be necessary for a full-featured application.
Finally, we’re going to add one piece of XAML and an event handler in case the image gets lost so that the user can reset the zoom and position of the original image:
Since the ViewportWidth indicates how far the image is zoomed, we simply tell our control to ZoomAboutLogicalPoint with ViewportWidth as the first argument. We then reset the position to the center of the image.
To view the final project: http://www.agilemedicine.com/resources/DeepZoomExample
We’ll get the full source code posted soon. If you have any questions or comments, feel free to leave them below or e-mail us at firstname.lastname@example.org.