Scale WPF canvas relative to center, not top left
I am writing a program to create shortcuts. In this program I have a canvas with a white rectangle in the center, with several objects that the user can resize, drag and drop, etc. Over it. I also have the option to zoom in on the canvas, which I do using ScaleTransform
via LayoutTransform
. I want to have it so that when the user zooms in, the canvas zooms in at the center and not in relation to the top right.
Here's a demo:
The canvas is currently scaled like this:

I need it to be like this:

How can I accomplish this task without rearranging the elements in the canvas as it zooms in?
Note . I am using LayoutTransform since I have to insert this into ScrollViewer
. RenderTransform
does this, but prevents the user from scrolling when canvas elements exceed the visible boundaries of the canvas.
You should be able to accomplish the same as RenderTransformOrigin using a transform that combines the two translations around scaling. For example. using TransformGroup or combining matrices for MatrixTransform.
Specifically: translate the center point (X, Y) to (0,0) using the shift offsets -X and -Y, do a scale transformation, and then translate (0,0) back to the origin (X, Y) using X and Y shear displacement.
It's hard for me to know for sure without having a specific code example, but I have a vague feeling that a RenderTransform should be used, possibly applied differently than you would prefer (for example, adding a new container to the hierarchy and applying to it). But assuming the RenderTransform just doesn't work, the above should be.
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="600" Width="600">
<Grid>
<ScrollViewer>
<Border>
<Border.LayoutTransform>
<TransformGroup>
<ScaleTransform ScaleX="2.0" ScaleY="2.0"/>
</TransformGroup>
</Border.LayoutTransform>
<Canvas Background="Red" Width="500" Height="500" VerticalAlignment="Center" HorizontalAlignment="Center">
<Canvas.RenderTransform>
<TransformGroup>
<TranslateTransform X="0" Y="-100"/>
</TransformGroup>
</Canvas.RenderTransform>
<Rectangle Canvas.Left="200" Canvas.Top="200" Width="100" Height="100" Fill="Yellow"/>
</Canvas>
</Border>
</ScrollViewer>
</Grid>
</Window>