This way quite tricky :cool:
Sorry for waiting so long - I working on new version of Reader3ds.
So here is the solution:
The XAML part is the same as before:
The tricky part is in the code:
This should work.
The code will be probably included into next version of ZoomPanel (cannot say when it will be published).
Thank you for your recommendation.
Sorry for waiting so long - I working on new version of Reader3ds.
So here is the solution:
The XAML part is the same as before:
Code:
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:zoomPanel="clr-namespace:Ab2d.Controls;assembly=Ab2d.Controls.ZoomPanel"
Title="Window1" Height="300" Width="300"
MouseWheel="Window_MouseWheel">
<Grid>
<zoomPanel:ZoomPanel Name="ZoomPanel1" IsMouseWheelZoomEnabled="False" ZoomMode="Move">
<TextBlock Text="12345"/>
</zoomPanel:ZoomPanel>
</Grid>
</Window>
The tricky part is in the code:
Code:
private void Window_MouseWheel(object sender, MouseWheelEventArgs e)
{
Point mousePosition;
double zoomFactor;
if (e.Delta > 0)
zoomFactor = 1.3;
else
zoomFactor = 1 / 1.3;
mousePosition = e.GetPosition(ZoomPanel1);
ZoomPanel1.Viewbox = GetNewViewbox(zoomFactor, mousePosition);
e.Handled = true;
}
private Rect GetNewViewbox(double zoomFactor, Point mousePosition)
{
UIElement content;
double zoomPanelAspectRatio, contentAspectRatio;
double aspect;
Rect newViewbox;
Point relativeMousePosition;
Point relativeViewboxPosition;
Point relativeViewboxPosition2;
Rect actualViewbox1, actualViewbox2;
content = ZoomPanel1.Content as UIElement;
if (content == null)
return ZoomPanel1.Viewbox;
zoomPanelAspectRatio = ZoomPanel1.ActualWidth / ZoomPanel1.ActualHeight;
contentAspectRatio = content.DesiredSize.Width / content.DesiredSize.Height;
// Apsect ration between ZoomPanel and its content
aspect = contentAspectRatio / zoomPanelAspectRatio;
relativeMousePosition = new Point(mousePosition.X / ZoomPanel1.ActualWidth,
mousePosition.Y / ZoomPanel1.ActualHeight);
// Calculate actual viewbox
actualViewbox1 = AdjustRectForAspectRatio(ZoomPanel1.Viewbox, aspect);
// mouse position on the original actual viewbox
relativeViewboxPosition = new Point(actualViewbox1.X + actualViewbox1.Width * relativeMousePosition.X,
actualViewbox1.Y + actualViewbox1.Height * relativeMousePosition.Y);
// Do the normal zoom to the current center point for the zoomFactor
double viewboxDx, viewboxDy;
// viewboxDx and viewboxDy are the actual viewbox changes
viewboxDx = ZoomPanel1.Viewbox.Width - (ZoomPanel1.Viewbox.Width / zoomFactor);
viewboxDy = ZoomPanel1.Viewbox.Height - (ZoomPanel1.Viewbox.Height / zoomFactor);
newViewbox = new Rect(ZoomPanel1.Viewbox.X + viewboxDx / 2,
ZoomPanel1.Viewbox.Y + viewboxDy / 2,
ZoomPanel1.Viewbox.Width - viewboxDx,
ZoomPanel1.Viewbox.Height - viewboxDy);
// Now get where the mouse position would be in the newViewbox
actualViewbox2 = AdjustRectForAspectRatio(newViewbox, aspect);
relativeViewboxPosition2 = new Point(actualViewbox2.X + actualViewbox2.Width * relativeMousePosition.X,
actualViewbox2.Y + actualViewbox2.Height * relativeMousePosition.Y);
// Adjust the newViewbox so the objects under the mouse position stay on the same place
newViewbox.X -= relativeViewboxPosition2.X - relativeViewboxPosition.X;
newViewbox.Y -= relativeViewboxPosition2.Y - relativeViewboxPosition.Y;
return newViewbox;
}
private Rect AdjustRectForAspectRatio(Rect originalRect, double aspect)
{
Rect adjustedRect;
adjustedRect = originalRect;
if (aspect > 1) // content wider than ZoomPanel
{
//actualViewbox2.Y = actualViewbox1.Y * aspect - (actualViewbox1.Height * (aspect - 1) / 2);
adjustedRect.Y *= aspect;
adjustedRect.Height *= aspect;
}
else
{
adjustedRect.X /= aspect;
adjustedRect.Width /= aspect;
}
return adjustedRect;
}
This should work.
The code will be probably included into next version of ZoomPanel (cannot say when it will be published).
Thank you for your recommendation.