This article is compatible with the latest version of Silverlight.
You are not familiar with the MultiscaleImage control, are you? Read this article.
When using MultiscaleImage control with its zoom functionality, it's really useful to set a maximum and a minimum level for the zoom. The reason is that sometimes there is no reason to zoom - the image either becomes too small and is almost not visible at all or it gets so big that you can't see any details. Adding such levels will allow you to make the behavior of your control more reasonable.
I'll extend the example from my article about the MultiscaleImage control. We add one new variable and two constants:
double zoomLevel = 1;
const double maxZoomLevel = 16;
const double minZoomLevel = 0.2;
The start zoomLevel is 1. The maxZoomLevel and the minZoomLevel depend on your desire, but it's good to consider them with the image resolution too.
I've created a method named Zoom, where the zoom functionality is done now. In it the zoomLevel gets compared with the min and max zoom levels:
private void Zoom( double zoomFactor, Point zoomPosition )
{
if( ( zoomLevel < maxZoomLevel && zoomFactor > 1 ) ||
( zoomLevel > minZoomLevel && zoomFactor < 1 ) )
{
MyMultiscaleImage.ZoomAboutLogicalPoint( zoomFactor, zoomPosition.X, zoomPosition.Y );
zoomLevel = zoomLevel * zoomFactor;
}
}
The valid situations are when we zoom in and the zoom level is smaller than the maximal zoom level and when we zoom out and the zoom level is greater than the minimal zoom level. If none of these situations is on hand, no zoom is done. After we've zoomed we have to calculate the new zoomLevel. It's equal to the old multiplied with the zoomFactor.
The method that I have described above is not always the best one, and there are cases, in which it don't work correctly. So I'll provide a more universal and reliable solution to the problem.
In this solution instead of the zoomLevel varaible we've created we use the ViewportWidth property of the MultiscaleImage control. It measures how much the image is zoomed - 1 for not zoomed image, 0.5 for 200% zoom and 2 for 50% zoom for example. Another advantage is that we don't have to set it every time we mess with the zoom. The control set it itself, so we always can get the current zoom level. Here is how the zoom method looks now:
public double ZoomLevel
{
get
{
return 1 / MyMultiscaleImage.ViewportWidth;
}
}
private void Zoom( double zoomFactor, Point zoomPosition )
{
if( ( ZoomLevel < maxZoomLevel && zoomFactor > 1 ) ||
( ZoomLevel > minZoomLevel && zoomFactor < 1 ) )
{
MyMultiscaleImage.ZoomAboutLogicalPoint( zoomFactor, zoomPosition.X, zoomPosition.Y );
}
}
The zoom level we need is reciprocal to the ViewportWidth of the image. The logic is the same, but in this case we don't have to update the zoom level every time. What do we win? We may have adjustments to the zoom in several methods, which means that in each of them we have to calculate the zoom level, but using the Viewport property we don't care when and how the level has changed, what matters is that it gets set automatically.
And that's all - we have extended the application to support maximal and minimal levels of zooming. Although this is a relatively small enhancement, it improves the user experience and gives the feeling that the application is even more completed than before. See the live demo here and download the source code here.