WPF多边形rotatetransform旋转移动方向

时间:2016-11-21 14:21:25

标签: c# wpf rotation polygon rotatetransform

所以我在WPF中构建这个应用程序,在那里我用箭头画一条线。箭头是在资源字典中创建的Polygon,如下所示:

<!-- This is the arrowhead of the wire -->
<Polygon x:Name="PART_arrow"
    Points="{Binding Path=ArrowPathData}" IsHitTestVisible="True"
    Stroke="{TemplateBinding Stroke}" StrokeThickness="{TemplateBinding InnerWireStrokeThickness}"
    Fill="White" RenderTransformOrigin="0,0.5" RenderTransform="{Binding ArrowRotation}">
</Polygon>

在视图模型中,我创建带有点集的箭头,其位置取决于线的最后一个关节的位置。最后箭头需要根据线的角度旋转,但这是为了以后。在这一刻,箭头被可视化并跟随线的最后一个关节。这仅在箭头旋转为0时有效。当我改变旋转时,箭头的移动也会改变。所以例如当我将旋转设置为90度时。箭头旋转90度,但当我向左移动线时,箭头移动到顶部。我试图将RenderTransform setter更改为LayoutTransform。我使用了Polygon.Rendertransform并硬编码了一个角度。但没有任何作用。

public PointCollection ArrowPathData
{
    get
    {
        PointCollection arrow = new PointCollection();

        if(isArrowSelected)
            arrow = PointCollection.Parse("0,0 3,5 0,0 -3,5");
        else if (isWindowSelected)
            arrow = PointCollection.Parse("0,0 5,10 0,20 -5,10");
        else if (isRoofSelected)
            arrow = PointCollection.Parse("0,0 5,10 -5,10");

        IEnumerable<WireJoint> joints = Joints;
        if (joints.Count<WireJoint>() > 0)
        {
            WireJoint lastJoint = joints.Last();

            if (lastJoint != null)
            {
                for (int i = 0; i < arrow.Count; i++)
                {
                    arrow[i] = new Point(lastJoint.Point.X + arrow[i].X - Offset.X, lastJoint.Point.Y + arrow[i].Y - Offset.Y);
                }
            }
            return arrow;
        }
        else
            return new PointCollection();
    }
}

public RotateTransform ArrowRotation
{
    get
    {
        return new RotateTransform(45) ;
    }
}

有人可以帮我解决这个问题吗?

编辑:在代码中添加了额外的箭头

1 个答案:

答案 0 :(得分:0)

您可能希望使用从折线的最后两个点创建变换几何的Binding Converter:

public class ArrowHeadConverter : IValueConverter
{
    public object Convert(
        object value, Type targetType, object parameter, CultureInfo culture)
    {
        Geometry geometry = null;
        var points = value as IList<Point>;

        if (points != null && points.Count >= 2)
        {
            geometry = Geometry.Parse("M0,0 L5,10 -5,10Z").Clone();

            var lastPoint = points[points.Count - 1];
            var lastSegment = lastPoint - points[points.Count - 2];
            var angle = Vector.AngleBetween(new Vector(0, -1), lastSegment);
            var transform = Matrix.Identity;

            transform.Rotate(angle);
            transform.Translate(lastPoint.X, lastPoint.Y);

            geometry.Transform = new MatrixTransform(transform);
        }

        return geometry;
    }

    public object ConvertBack(
        object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

您可以像这个简单示例一样使用转换器:

<Canvas>
    <Canvas.Resources>
        <local:ArrowHeadConverter x:Key="ArrowHeadConverter"/>
    </Canvas.Resources>

    <Polyline x:Name="polyline" Stroke="Black" StrokeThickness="2"
              Points="10,10 50,20 70,40 80,60"/>

    <Path Fill="White" Stroke="Black" StrokeThickness="2"
          Data="{Binding Points, ElementName=polyline,
                         Converter={StaticResource ArrowHeadConverter}}"/>
</Canvas>