在WPF中绘制圆圈

时间:2011-06-28 14:09:15

标签: c# wpf shape adorner

我正在尝试编写一个WPF应用程序,您可以通过双击在窗口上绘制圆圈。到目前为止,我有这段代码:

public class ShapeAdorner : Adorner
{
    private readonly Ellipse _circle;

    public ShapeAdorner(UIElement adornedElement, Point circleCenter)
        : base(adornedElement)
    {
        _circle = new Ellipse
        {
            Width = 10,
            Height = 10,
            Stroke = Brushes.Black,
            StrokeThickness = 1.5
        };
        _circle.Margin =
            new Thickness(left: circleCenter.X, top: circleCenter.Y, right: 0, bottom: 0);
        base.AddVisualChild(_circle);
    }

    protected override Size ArrangeOverride(Size finalSize)
    {
        _circle.Arrange(new Rect(finalSize));
        return finalSize;
    }

    protected override Size MeasureOverride(Size constraint)
    {
        _circle.Measure(constraint);
        return constraint;
    }

    protected override Visual GetVisualChild(int index)
    {
        return _circle;
    }

    protected override int VisualChildrenCount
    {
        get { return 1; }
    }
}

这是客户端代码:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Window_MouseDoubleClick(object sender, MouseButtonEventArgs e)
    {
        AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(myLabel);
        adornerLayer.Add(new ShapeAdorner(adornedElement: myLabel, circleCenter: e.GetPosition(myLabel)));
    } 
}

圆圈应该位于双击窗口的位置;但是,上面代码绘制的圆圈位于“双击点”的下方和右侧。如何解决这个问题?

编辑:myLabelHeight=350Width=525。假设我双击(X,Y)点;然后圆圈被绘制在((350+X)/2,(525+Y)/2)

编辑2:为了完整起见,这是.xaml文件:

<Window x:Class="Adorners.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Adorners project" Height="350" Width="525" MouseDoubleClick="Window_MouseDoubleClick">
    <Grid>
        <Label Name="myLabel" Content="my label" Background="Red"></Label>
    </Grid>
</Window>

4 个答案:

答案 0 :(得分:2)

在设置边距的情况下,您必须从顶部和左侧属性中减去半径以偏移圆。

答案 1 :(得分:1)

您需要将圆的宽度/高度的一半偏移。这里硬编码使其易于理解:

AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(myLabel);
var point = e.GetPosition(myLabel);
point.X -= 5;
point.Y -= 5;
adornerLayer.Add(new ShapeAdorner(myLabel, point));

答案 2 :(得分:1)

在设置边距时,需要考虑宽度和高度。顶部应该是中心位置减去高度的一半,左边是相同的:

new Thickness(
     left: circleCenter.X + (_circle.Width/2), //farther to the right
     top: circleCenter.Y - (_circle.Height/2), //higher up
     right: 0, bottom: 0);

答案 3 :(得分:0)

之前的答案是正确的。然而,主要问题是我省略了这两行:

_circle.HorizontalAlignment = HorizontalAlignment.Left;
_circle.VerticalAlignment = VerticalAlignment.Top;

默认值Stretch导致巨大的偏移误差。