I have a ToolWindow that acts as a image viewer. You can zoom/pan around the image. Pinch functionality does not work within the ToolWindow, but does within a Workspace. Repo steps:
- Create a new WPF application
- Add a reference to docking tools
- Add the following in the MainWindow
<docking:DockSite > <docking:SplitContainer> <docking:Workspace> </docking:Workspace> <docking:ToolWindowContainer> <docking:ToolWindow Title="Image Gallery"> <Border Background="Black" ClipToBounds="True" IsManipulationEnabled="True" ManipulationDelta="Border_ManipulationDelta" MouseMove="Border_MouseMove" MouseLeftButtonDown="Border_MouseLeftButtonDown" MouseLeftButtonUp="Border_MouseLeftButtonUp" MouseWheel="Border_MouseWheel"> <Image x:Name="Image" RenderTransformOrigin=".5,.5"/> </Border> </docking:ToolWindow> </docking:ToolWindowContainer> </docking:SplitContainer> </docking:DockSite>
- Add the follow in the code behind
private void Border_ManipulationDelta(object sender, ManipulationDeltaEventArgs e) { System.Diagnostics.Debug.WriteLine("Manipulation: " + e.DeltaManipulation.Translation); System.Diagnostics.Debug.WriteLine(" Translation.X: " + e.DeltaManipulation.Translation.X); System.Diagnostics.Debug.WriteLine(" Translation.Y: " + e.DeltaManipulation.Translation.Y); System.Diagnostics.Debug.WriteLine(" Scale.X: " + e.DeltaManipulation.Scale.X); System.Diagnostics.Debug.WriteLine(" Scale.Y: " + e.DeltaManipulation.Scale.Y); Border b = (Border)sender; MatrixTransform mt = (MatrixTransform)Image.RenderTransform; Matrix m = mt.Matrix; m.OffsetX += e.DeltaManipulation.Translation.X; m.OffsetY += e.DeltaManipulation.Translation.Y; m.M11 *= e.DeltaManipulation.Scale.X; m.M22 *= e.DeltaManipulation.Scale.Y; m = FitMatrixToBounds(m, new Size(Image.ActualWidth, Image.ActualHeight), new Size(b.ActualWidth, b.ActualHeight)); Image.RenderTransform = new MatrixTransform(m); } private void Border_MouseMove(object sender, MouseEventArgs e) { Border b = (Border)sender; if (b.IsMouseCaptured) { Point p = e.GetPosition(b); MatrixTransform mt = (MatrixTransform)Image.RenderTransform; Matrix m = mt.Matrix; if (m.M11 != 1) { m.OffsetX += p.X - _dragOrigin.X; m.OffsetY += p.Y - _dragOrigin.Y; m = FitMatrixToBounds(m, new Size(Image.ActualWidth, Image.ActualHeight), new Size(b.ActualWidth, b.ActualHeight)); Image.RenderTransform = new MatrixTransform(m); } _dragOrigin = p; } } private void Border_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { if(e.ClickCount % 2 == 0) { Border_MouseWheel(sender, new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, 1)); return; } Border b = (Border)sender; _dragOrigin = e.GetPosition(b); b.CaptureMouse(); } private void Border_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { Border b = (Border)sender; b.ReleaseMouseCapture(); } private void Border_MouseWheel(object sender, MouseWheelEventArgs e) { Border b = (Border)sender; double zoom = e.Delta > 0 ? 2 : 0.5; MatrixTransform mt = (MatrixTransform)Image.RenderTransform; Matrix m = mt.Matrix; m.M11 *= zoom; m.M22 *= zoom; m = FitMatrixToBounds(m, new Size(Image.ActualWidth, Image.ActualHeight), new Size(b.ActualWidth, b.ActualHeight)); Image.RenderTransform = new MatrixTransform(m); } private Matrix FitMatrixToBounds(Matrix m, Size size, Size bounds) { if (m.M11 < 1) { return Matrix.Identity; } if (m.M11 == 1) { m.OffsetX = m.OffsetY = 0; } else { var maxWidth = Math.Abs(((size.Width * m.M11) - bounds.Width) / 2); var maxHeight = Math.Abs(((size.Height * m.M22) - bounds.Height) / 2); if (Math.Abs(m.OffsetX) > maxWidth) { if (m.OffsetX > 0) m.OffsetX = maxWidth; else m.OffsetX = -maxWidth; } if (Math.Abs(m.OffsetY) > maxHeight) { if (m.OffsetY > 0) m.OffsetY = maxHeight; else m.OffsetY = -maxHeight; } } return m; }
- Make sure to set the source for the Image
- Run the application.
- Use the mouse to scroll in out of the image. -- Should work fine
- Use the mouse to move the image around (provided it is zoomed in) -- should work fine
- Using a touch monitor pan the image (provided it is zoomed in) -- should work fine
- Using a touch monitor, pinch to zoom in/out of the image. -- will not work
- Move the Border element into the Workspace and repeat steps 6-10. Everything should work fine.
I'm pretty sure this worked before upgrading the docking tools (previous framework)