Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Positioning an element inside the Canvas by its center (instead of the top left corner) using only XAML in Silverlight/WinRT

The common question about positioning an element inside a Canvas is "How to position the center of element (instead of the top left corner)".

  • WPF: Resizing a circle, keeping the center point instead of TopLeft?
  • WPF Center Ellipse at X, Y
  • WPF element positioning on a Canvas

Several solutions are presented, but they all have drawbacks.

Is there a simple (XAML-only) method to position an element inside canvas so that its Canvas.Left and Canvas.Top correspond to the element's center AND both size and position properties can be bound to some other properties?

I've found a very easy way to do this in WPF (just set Margin="-1000000" Positioning an element inside the Canvas by its center (instead of the top left corner) using only XAML in WPF), but it doesn't work for Silverlight/WinRT. The only other method that I know requires creating ValueConverter to perform the x *= -0.5 calculation (which is not XAML-only).

like image 915
Ark-kun Avatar asked Nov 03 '22 12:11

Ark-kun


1 Answers

While it's not pretty, here's an example of using nested RenderTransforms with different origins to offset the position of the object to make it so that it's centered:

<UserControl x:Class="UrlTest.Center"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Canvas x:Name="LayoutRoot" Background="White">
        <ContentControl Canvas.Top="100" Content="{Binding ActualWidth,ElementName=Center, StringFormat=Width \{0\}}"/>
        <ContentControl Canvas.Top="120" Content="{Binding ActualHeight,ElementName=Center, StringFormat=Height \{0\}}"/>
        <Grid x:Name="Center" RenderTransformOrigin="-.5,-.5" Canvas.Left="40" Canvas.Top="25">
            <Grid.RenderTransform>
                <ScaleTransform ScaleX="-1" ScaleY="-1"/>
            </Grid.RenderTransform>
            <Grid RenderTransformOrigin="-.25,-.25">
                <Grid.RenderTransform>
                    <ScaleTransform ScaleX="-1" ScaleY="-1"/>
                </Grid.RenderTransform>
                <Ellipse Width="80" Height="50" Fill="Aquamarine"/>
                <ContentControl FontSize="20" HorizontalContentAlignment="Center" VerticalContentAlignment="Center">Center</ContentControl>
            </Grid>
        </Grid>
    </Canvas>
</UserControl>

The inner Grids are for creating the transforms, while the outer Canvas is there to make sure the Grid inside of it sets its size to that of the content inside of it.

like image 170
Gabe Avatar answered Nov 09 '22 15:11

Gabe