WPF element positioning on a Canvas

2020-04-16 04:28发布

问题:

I have a point on a canvas that I want to place an ellipse. I want the centre of the ellipse to be over this point. At the moment the top left most edge of the ellipse is over this point.

I know I can shift the ellipse programmatically on the canvas but I was wondering if there is a way to tell WPF to centre the element over the point instead of sizing it from the top left???

回答1:

I do not know of any in built in feature in Ellipse to set its center on a point, but you can extend the Ellipse class to do it.

Add this class to project

public static class EllipseX 
{
    public static void SetCenter(this Ellipse ellipse, double X, double Y)
    {
        Canvas.SetTop(ellipse, Y - ellipse.Height/2);
        Canvas.SetLeft(ellipse, X - ellipse.Width/2);
    }
}

Then in xaml create the Ellipse

<Window x:Class="WpfApplication2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
   <Canvas Background="LightGray">
      <Ellipse      
          Name="myEllipse"      
          Fill="Red"
          Height="75"
          Width="75"
       />
   </Canvas>
</Window>

Then write int following code in code behind:

myEllipse.SetCenter(200,200);

The advantage of this is that you do not have to repeat the logic of finding center in every ellipse you create.

Hope this helps.



回答2:

No there is no such way. Top Left is a top left, because it's a top left :). Alternatively instead of shifting ellipse you can shift point, if you know ellipse dimensions.



回答3:

You could apply a TranslateTransform to the Ellipse, but that requires you to know its width and height.



回答4:

I had a similar problem setting the Center of a ScaleTransform in a style of different sized controls. Ended up using a converter to bind to the ActualWidth/ActualHeight divided by 2. THe same should work for you with a TranslateTransform as Rune Grimstad mentioned.

<ScaleTransform CenterX="{Binding ActualWidth, Converter={StaticResource divisionConverter}}"
                CenterY="{Binding ActualHeight, Converter={StaticResource divisionConverter}}"
                ScaleX="1.2"
                ScaleY="1.2" />