Daily Demos: Deep Zoom Mouse Zoom Features
Deep Zoom is brilliant, awesome, super exciting … I LOVE DEEP ZOOM. And I love to create my own applications based on Deep Zoom. In Silverlight you can use Deep Zoom with the MultiScaleImage-Control. The challenge is, it doesn’t bring support for navigation in a deep zoom image. So you have to do it by yourself … or better use a Behavior for this features.
XAML-Code
<UserControl
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="https://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:TheOliver_Controls="clr-namespace:TheOliver.Controls"
x:Class="DeepZoomMouseBehavior.MainPage"
d:DesignHeight="300"
d:DesignWidth="400">
<Grid
x:Name="LayoutRoot"
Background="White">
<TextBlock
Text="Deep Zoom Sample" />
<MultiScaleImage
x:Name="_msi"
Source="Images/dzc_output.xml"
Margin="0,12,0,0">
<i:Interaction.Behaviors>
<TheOliver_Controls:DeepZoomBehavior />
</i:Interaction.Behaviors>
</MultiScaleImage>
</Grid>
</UserControl>
Sourcecode
// Copyright © Microsoft Corporation. All Rights Reserved.
// This code released under the terms of the
// Microsoft Public License (MS-PL, https://opensource.org/licenses/ms-pl.html.)
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interactivity;
namespace TheOliver.Controls
{
public class DeepZoomBehavior : Behavior<MultiScaleImage>
{
MultiScaleImage _msi;
Point _lastMousePos = new Point();
double _zoom = 1;
bool _mouseButtonPressed = false;
bool _mouseIsDragging = false;
Point _dragOffset;
Point _currentPosition;
private double ZoomFactor
{
get { return _zoom; }
set { _zoom = value; }
}
protected override void OnAttached()
{
_msi = this.AssociatedObject;
_msi.MouseMove += delegate(object sender, MouseEventArgs e)
{
if (_mouseButtonPressed)
{
_mouseIsDragging = true;
}
_lastMousePos = e.GetPosition(_msi);
};
_msi.MouseLeftButtonDown += delegate(object sender, MouseButtonEventArgs e)
{
_mouseButtonPressed = true;
_mouseIsDragging = false;
_dragOffset = e.GetPosition(_msi);
_currentPosition = _msi.ViewportOrigin;
};
_msi.MouseLeave += delegate(object sender, MouseEventArgs e)
{
_mouseIsDragging = false;
};
_msi.MouseLeftButtonUp += delegate(object sender, MouseButtonEventArgs e)
{
_mouseButtonPressed = false;
if (_mouseIsDragging == false)
{
bool shiftDown = (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift;
ZoomFactor = 2.0;
if (shiftDown) ZoomFactor = 0.5;
Zoom(ZoomFactor, _lastMousePos);
}
_mouseIsDragging = false;
};
_msi.MouseMove += delegate(object sender, MouseEventArgs e)
{
if (_mouseIsDragging)
{
Point newOrigin = new Point();
newOrigin.X = _currentPosition.X - (((e.GetPosition(_msi).X - _dragOffset.X) / _msi.ActualWidth) * _msi.ViewportWidth);
newOrigin.Y = _currentPosition.Y - (((e.GetPosition(_msi).Y - _dragOffset.Y) / _msi.ActualHeight) * _msi.ViewportWidth);
_msi.ViewportOrigin = newOrigin;
}
};
_msi.MouseWheel += (s,e) =>
{
e.Handled = true;
if (e.Delta > 0)
{
ZoomFactor = 1.2;
}
else
{
ZoomFactor = .80;
}
Zoom(ZoomFactor, _lastMousePos);
};
}
public void Zoom(double zoom, Point pointToZoom)
{
Point logicalPoint = _msi.ElementToLogicalPoint(pointToZoom);
_msi.ZoomAboutLogicalPoint(zoom, logicalPoint.X, logicalPoint.Y);
}
}
}