关于C#:Arc无法在WPF画布上显示?

Arc doesn't shows on wpf canvas?

我将要创建一个可以从(X1,Y1)点到(X2,Y2)点绘制圆弧的应用程序。

(X1,X2)是我在画布上单击的第一点,而(X2,Y2)是我在画布上单击的第二点。第一次单击时,将保存第一个弧点(X1,Y1),而第二个弧点是相对于鼠标指针的,因此,通过这种方式,我可以灵活地调整画布的宽度,这是" GHOST"弧在向用户最终显示第二次单击之前(无需按住点击),以可视方式向用户显示弧度。

A"GHOST" is when on, let say, power point, you insert a line, you
hold the first click, and then move your mouse around, the end point
on the line looks like it connected to the mouse pointer until the
left click released. It's visually like a line, but until you release your click
the line isn't"drawn" and still can be flexibly adjusted.

但是,Y2始终等于Y1,这意味着弧线的两侧始终在相同的Y上。

这是我的XAML:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<Window x:Class="Drawing.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">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>

    <TextBox Grid.Row="0" Height="25" IsEnabled="False" Name="txt" Grid.ColumnSpan="2"/>
    <TextBox Grid.Column="0" Grid.Row="1" Width="100"/>
    <Canvas Name="cnv" MouseLeftButtonDown="cnv_MouseLeftButtonDown" Background="Transparent" Grid.Row="1"
            Grid.Column="1" MouseMove="cnv_MouseMove"/>
</Grid>
</Window>

这是我的MainWindow类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
    Ellipse ellipse = null;

    public MainWindow()
    {
        InitializeComponent();
    }

    private void cnv_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        Point p = Mouse.GetPosition(cnv);

        txt.Text = p.ToString();

        if (ellipse == null)
        {
            Point first = p;
            ellipse = new Ellipse();
            ellipse.Fill = Brushes.Transparent;
            ellipse.Stroke = Brushes.Black;
            ellipse.StrokeThickness = 1;

            Canvas.SetTop(cnv, p.Y);
            Canvas.SetLeft(cnv, p.X);
            ellipse.Width = p.X - Canvas.GetLeft(ellipse);
            ellipse.Height = 20;
            ellipse.Clip = new RectangleGeometry(new Rect(0, ellipse.Height / 2, ellipse.Width, ellipse.Height));

            cnv.Children.Add(ellipse);
        }
        else
        {
            ellipse = null;
        }
    }

    private void cnv_MouseMove(object sender, MouseEventArgs e)
    {
        Point p = Mouse.GetPosition(cnv);

        txt.Text = p.ToString();

        if (ellipse != null)
        {
            ellipse.Width = p.X - Canvas.GetLeft(ellipse);
            ellipse.Height = 20;
            ellipse.Clip = new RectangleGeometry(new Rect(0, ellipse.Height / 2, ellipse.Width, ellipse.Height));
        }
    }

有什么办法解决这个问题吗?

P.S。我并不是严格讲椭圆形的,如果您可以向我展示另一种方式,那就很好。但是,我坚持要在代码背后而不是XAML上执行此操作。

P.S.S。第二次单击后无法编辑我的弧,只能将其删除。

P.S.S.S。在绘制弧线之前,我已经用相同的方法绘制了一条线,并且效果很好。区别是线上有X1,Y2,X2,Y2,而椭圆没有(我认为这是问题所在,但我不知道如何解决它。也许我错了)。

P.S.S.S.S。额外的怪异现象:第一次单击时,画布的左上角会有一条黑色的线闪烁,但是当我移动鼠标时,该线消失了。我不知道那是什么。

谢谢


您必须在椭圆而不是画布上设置Canvas.LeftCanvas.Top

cnv_MouseLeftButtonDown中的

更改

1
2
Canvas.SetTop(cnv, p.Y);
Canvas.SetLeft(cnv, p.X);

1
2
Canvas.SetTop(ellipse, p.Y);
Canvas.SetLeft(ellipse, p.X);

另一个错误是cnv_MouseMove,其中表达式

1
ellipse.Width = p.X - Canvas.GetLeft(ellipse);

尝试在鼠标指针向左移动超出起点时为椭圆分配负宽度。


我不太确定我了解您如何尝试指定圆弧,但是我使用以下代码为我的程序绘制了一个圆弧(更像是一块饼)(也许您会找到一些东西)您可以在这里使用):

1
2
3
4
5
6
7
8
9
10
11
12
OrientSegment = new PathGeometry();
PathFigure figure = new PathFigure();
//Offset is used to convert from clock face radians (starting at top) to system radians (off by 90 degrees, or Tau/4)
double offset = -IRMath.Tau / 4;
Point start = new Point(radius * Math.Cos(minRadians + offset), radius * Math.Sin(minRadians + offset));
Point end = new Point(radius * Math.Cos(minRadians + offset + radianSpan), radius * Math.Sin(minRadians + offset + radianSpan));
figure.StartPoint = new Point(0, 0);
figure.Segments.Add(new LineSegment(start, false));
figure.Segments.Add(new ArcSegment(end, new Size(radius, radius), 0, radianSpan > Math.PI, SweepDirection.Clockwise, true));
figure.Segments.Add(new LineSegment(figure.StartPoint, false));

OrientSegment.Figures.Add(figure);

只有XAML的一行:

1
<Path x:Name="SegmentPath" Data="{Binding OrientSegment, ElementName=root}" Canvas.Left="30" Canvas.Top="30" Fill="{Binding SegmentBrush, ElementName=root}" Stroke="{DynamicResource OrientationSegmentStroke}" StrokeThickness="4"/>