WPF: how to make the (0,0) in center inside a Canvas WPF: how to make the (0,0) in center inside a Canvas wpf wpf

WPF: how to make the (0,0) in center inside a Canvas


There is no need to create a custom Panel. Canvas will do just fine. Simply wrap it inside another control (such as a border), center it, give it zero size, and flip it with a RenderTransform:

<Border>  <Canvas HorizontalAlignment="Center" VerticalAlignment="Center"          Width="0" Height="0"          RenderTransform="1 0 0 -1 0 0">    ...  </Canvas></Border>

You can do this and everything in the canvas will still appear, except (0,0) will be at the center of the containing control (in this case, the center of the Border) and +Y will be up instead of down.

Again, there is no need to create a custom panel for this.


It was very easy to do. I looked at the original Canvas's code using .NET Reflector, and noticed the implementation is actually very simple. The only thing required was to override the function ArrangeOverride(...)

public class CartesianCanvas : Canvas{    public CartesianCanvas()    {        LayoutTransform = new ScaleTransform() { ScaleX = 1, ScaleY = -1 };    }    protected override Size ArrangeOverride( Size arrangeSize )    {        Point middle = new Point( arrangeSize.Width / 2, arrangeSize.Height / 2 );        foreach( UIElement element in base.InternalChildren )        {            if( element == null )            {                continue;            }            double x = 0.0;            double y = 0.0;            double left = GetLeft( element );            if( !double.IsNaN( left ) )            {                x = left;            }            double top = GetTop( element );            if( !double.IsNaN( top ) )            {                y = top;            }            element.Arrange( new Rect( new Point( middle.X + x, middle.Y + y ), element.DesiredSize ) );        }        return arrangeSize;    }}


You can simply change the Origin with RenderTransformOrigin.

    <Canvas Width="Auto" Height="Auto"            HorizontalAlignment="Center"            VerticalAlignment="Center"            RenderTransformOrigin="0.5,0.5">        <Canvas.RenderTransform>            <TransformGroup>                <ScaleTransform ScaleY="-1" ScaleX="1" />            </TransformGroup>        </Canvas.RenderTransform>    </Canvas>