在WPF中绘制圆圈

发布于 2024-11-17 16:04:36 字数 2201 浏览 4 评论 0原文

我正在尝试编写一个 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)));
    } 
}

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

编辑:myLabel 具有 Height=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>

I am trying to write a WPF application where you can draw circles on a window by double clicking it. So far I have this code:

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; }
    }
}

Here's the client code:

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)));
    } 
}

The circles are supposed to be centered at the point where you double click the window; however, the circles drawn by the code above are centered below and to the right of "the double click point". How can this be fixed?

EDIT: myLabel has Height=350 and Width=525. Let's say that I double click the point (X,Y); then the circle gets plotted at ((350+X)/2,(525+Y)/2).

EDIT 2: Just for completeness, here's the .xaml file:

<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>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

街道布景 2024-11-24 16:04:37

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

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

You'll need to offset by half the width/height of the circle. Hard-coded here to make it easy to follow:

AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(myLabel);
var point = e.GetPosition(myLabel);
point.X -= 5;
point.Y -= 5;
adornerLayer.Add(new ShapeAdorner(myLabel, point));
孤独陪着我 2024-11-24 16:04:37

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

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

You need to take the witdth and height into conserderation when you're setting the margin. the top should be the centerposition minus half of the height, and the same for the left:

new Thickness(
     left: circleCenter.X + (_circle.Width/2), //farther to the right
     top: circleCenter.Y - (_circle.Height/2), //higher up
     right: 0, bottom: 0);
朦胧时间 2024-11-24 16:04:37

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


_circle.Horizo​​ntalAlignment = Horizo​​ntalAlignment.Left;
_circle.VerticalAlignment = VerticalAlignment.Top;

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

The previous answers are correct. However, the main problem was that I had omitted these two lines:


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

The default value Stretch caused a huge offset error.

自此以后,行同陌路 2024-11-24 16:04:36

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

Where you set the margin you have to subtract the radius from the top and left properties to offset the circle.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文