title: WPF Canvas Scaling/Transform to Fit
body: <p>I'm reposting this question as I didn't get much of a response last time, hopefully a bit of re-wording might help...</p>
  
  <p>Essentially what I'm trying to do is to create a databound canvas, that will automatically scale its contents to 'fill' up the available space. Sort of like a zoom to fit operation. Unfortunately my WPF skills aren't yet very strong, and I'm struggling to work out how to do this last part. I've followed some databinding examples to get the canvas bound, but not sure if maybe its wrong and hindering me.</p>
  
  <p>I've got two basic problems at the moment depending on the way I try and tackle the solution, either:</p>
  
  <ul>
  <li>I don't know how to make the
  canvas re-scale automatically
  through XAML if its possible using a
  transform.     </li>
  <li>I can't seem to
  reference the canvas in the behind
  code, I'm guessing because its part
  of an ItemsControl?</li>
  </ul>
  
  <p>An example of what I'm trying to achieve, I've got A I want to try and get B:</p>
  
  <p>(<em>removed expired link to an img</em>)</p>
  
  <p>The code I'm currently using is pretty simple, just creating 4 dots with a given co-ordinate, and a another view model to wrap these up in.</p>
  
  <pre><code>public class PointCollectionViewModel
  {
      private List&lt;PointViewModel&gt; viewModels;
      public PointCollectionViewModel()
      {
          this.viewModels = new List&lt;PointViewModel&gt;();
          this.viewModels.Add(new PointViewModel(new Point(1, 1)));
          this.viewModels.Add(new PointViewModel(new Point(9, 9)));
          this.viewModels.Add(new PointViewModel(new Point(1, 9)));
          this.viewModels.Add(new PointViewModel(new Point(9, 1)));
      }
  
      public List&lt;PointViewModel&gt; Models
      {
          get { return this.viewModels; }
      }
  }
  
  public class PointViewModel
  {
     private Point point;
     public PointViewModel(Point point)
     {
         this.point = point;
     }
  
     public Double X { get { return point.X; } }
     public Double Y { get { return point.Y; } }
  }
  </code></pre>
  
  <p>Then the PointCollectionViewModel is used as the DataContent for my AutoResizingCanvas, which has the following XAML to implement the binding:</p>
  
  <pre><code>&lt;UserControl x:Class="WpfCanvasTransform.AutoResizingCanvas"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:local="clr-namespace:WpfCanvasTransform"
      x:Name="parent"&gt;
      &lt;ItemsControl x:Name="itemsControl" ItemsSource="{Binding Path=Models}"&gt;
      &lt;ItemsControl.ItemsPanel&gt;
          &lt;ItemsPanelTemplate&gt;
          &lt;Canvas x:Name="canvas" Background="DarkSeaGreen" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"&gt;
              &lt;Canvas.LayoutTransform&gt;
              &lt;ScaleTransform ScaleY="-1" /&gt;
              &lt;/Canvas.LayoutTransform&gt;
  
          &lt;/Canvas&gt;
          &lt;/ItemsPanelTemplate&gt;
      &lt;/ItemsControl.ItemsPanel&gt;
      &lt;ItemsControl.ItemTemplate&gt;
          &lt;DataTemplate DataType="{x:Type local:PointViewModel}"&gt;
          &lt;Ellipse Width="3" Height="3" Fill="Red"/&gt;
          &lt;/DataTemplate&gt;
      &lt;/ItemsControl.ItemTemplate&gt;
      &lt;ItemsControl.ItemContainerStyle&gt;
          &lt;Style&gt;
          &lt;Setter Property="Canvas.Top" Value="{Binding Path=Y}"/&gt;
          &lt;Setter Property="Canvas.Left" Value="{Binding Path=X}"/&gt;
          &lt;/Style&gt;
      &lt;/ItemsControl.ItemContainerStyle&gt;
      &lt;/ItemsControl&gt;
  &lt;/UserControl&gt;
  </code></pre>