【问题标题】:Arc doesn't shows on wpf canvas?弧不显示在 wpf 画布上?
【发布时间】:2014-05-20 19:18:32
【问题描述】:

我将制作一个应用程序,它可以绘制从 (X1,Y1) 点到 (X2,Y2) 的弧线。

(X1,X2) 是我在画布上单击的第一个点,(X2,Y2) 是第一次单击之后的第二次单击。当第一次点击时,第一个圆弧点(X1,Y1)被保存,第二个圆弧点是相对于鼠标指针的,所以这样我可以灵活地制作画布宽度,同时有一个“GHOST”ARC TO以视觉方式向用户展示在他们最终决定第二次点击之前如何制作弧线(无需按住点击)。

“GHOST”是当打开时,比如说,电源点,你插入一条线,你 按住第一次单击,然后移动鼠标,结束点 线上看起来像是连接到鼠标指针,直到 左键释放。它在视觉上像一条线,但在您释放点击之前 这条线不是“画”出来的,仍然可以灵活调整。

但是,Y2 总是等于 Y1,这意味着弧线在两边总是在同一个 Y 上。

这是我的 XAML:

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

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

知道如何解决这个问题吗?

附:我并不严格使用剪裁椭圆,如果你能告诉我另一种方法,那很好。但是,我坚持在代码隐藏而不是 XAML 上执行此操作。

附言第二次点击后我的圆弧无法编辑,只能删除。

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

P.S.S.S.S.额外的奇怪之处:当第一次点击时,我的画布左上角有一条黑线闪烁,但是当我移动鼠标时,这条线消失了。我想知道那是什么。

谢谢

【问题讨论】:

  • +1 以获得正确详细、格式正确的问题以及所有相关代码。
  • 谢谢。关于该主题的任何解决方案或某些观点可能有助于解决问题? :)

标签: c# wpf canvas draw


【解决方案1】:

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

cnv_MouseLeftButtonDown

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

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

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

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

当鼠标指针向左移动超出起点时,尝试为 Ellipse 分配负宽度。

【讨论】:

  • 哇,我不敢相信我错误地设置了画布,而不是椭圆。谢谢。
【解决方案2】:

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

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:

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

【讨论】:

  • @Moses Aprico 具体来说,看看 ArcSegment
猜你喜欢
  • 2016-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-25
  • 2016-07-07
  • 1970-01-01
相关资源
最近更新 更多