title: How to set panning limits on WPF Canvas based on zoom level?
body: <p>I'm trying to set <strong>zooming and panning limits</strong> on a control I found here:
  <a href="https://wpfextensions.codeplex.com" rel="nofollow noreferrer">https://wpfextensions.codeplex.com</a></p>
  
  <p>I managed to set zooming limits, but now I'm having <strong>trouble setting the panning limits</strong> so that you can't pan the object inside the canvas, outside the view.</p>
  
  <p>I succeeded in setting the limits, but only when the zoom level is 1 (<code>Zoom == 1</code>, so no zoom), but the moment you <strong>increase the zoom</strong> (by rotating the mouse wheel) <strong>things start to go wrong</strong>: the limits are set, but they are not set correctly.</p>
  
  <p>In order to set them correctly I have to take into consideration the <code>deltaZoom</code> (the amount zoom changed compared to the previous zoom value).</p>
  
  <h1>Small demo project</h1>
  
  <p>I have created a simple, standalone project where I can reproduce the issue:
  <a href="https://github.com/igorpopovio/CanvasZoomPan" rel="nofollow noreferrer">https://github.com/igorpopovio/CanvasZoomPan</a></p>
  
  <p>The project shows a desktop window with the <code>ZoomControl</code> (canvas with <code>ScaleTransform</code>, <code>TranslateTransform</code> and a bunch of dependency properties to make it easier to work with the transforms). The <code>ZoomControl</code> contains a red square and the window contains the <code>ZoomControl</code> and a debug list of properties so I can see live how they change based on left click drag and mouse wheel zoom.</p>
  
  <h1>Expected vs actual behaviour</h1>
  
  <p><strong>Expected behaviour</strong>: object/red square edge cannot get out of the current view.</p>
  
  <p><a href="https://i.stack.imgur.com/rnrpy.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/rnrpy.png" alt="Expected behaviour"></a></p>
  
  <p><br/></p>
  
  <p><strong>Actual behaviour</strong>: object/red square edge gets out of the current view (still has limits, but aren't correctly set).</p>
  
  <p><a href="https://i.stack.imgur.com/T74NX.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/T74NX.png" alt="Actual behaviour"></a></p>
  
  <h1>Code explanations</h1>
  
  <p>All the action happens in <a href="https://github.com/igorpopovio/CanvasZoomPan/blob/master/ZoomControl/ZoomControl.cs" rel="nofollow noreferrer"><strong>this file</strong></a> and the important bits are:</p>
  
  <ul>
  <li>the panning limits: <code>MinTranslateX, MaxTranslateX; MinTranslateY, MaxTranslateY</code>  </li>
  <li>the current panning: <code>TranslateX, TranslateY</code>  </li>
  <li>the current zoom: <code>Zoom</code>  </li>
  <li>the amount zoom changed: <code>deltaZoom</code> (local variable)  </li>
  <li>the <code>Zoom_PropertyChanged</code> method  </li>
  <li>the <code>LimitZoomingAndPanning</code> method  </li>
  </ul>
  
  <h1>What I tried</h1>
  
  <p>In the <code>LimitZoomingAndPanning</code> method I set the translation/panning limits which are working for <code>Zoom == 1</code> (<code>deltaZoom == 1</code>), but are giving incorrect limits for any other <code>Zoom</code> values:</p>
  
  <pre><code>MinTranslateX = box.BottomLeft.X * deltaZoom;
  MinTranslateY = box.BottomLeft.Y * deltaZoom;
  
  MaxTranslateX = ActualWidth - box.Size.Width * deltaZoom;
  MaxTranslateY = ActualHeight - box.Size.Height * deltaZoom;
  </code></pre>
  
  <p>The <code>box</code> variable is actually the bounding box of the object inside the canvas. <code>ActualWidth</code> and <code>ActualHeight</code> are the size of the canvas on which the object is rendered.</p>
  
  <p>Logically, all the translation/panning limits should depend on <code>deltaZoom</code>.</p>
  
  <p><strong>Maybe I'm missing something?</strong></p>