2016-11-21 10 views
0

그래서 WPF에서이 화살표를 사용하여 선을 그립니다. 화살촉은 아래와 같이 리소스 사전에서 만든 다각형입니다 :WPF 다각형 회전 변환은 이동 방향을 회전합니다.

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

내가 가진 pointcollection와 화살촉을 만드는거야 뷰 모델에서 라인의 마지막 관절의 위치에 따라 위치입니다. 결국 화살촉은 선의 각도에 따라 회전해야하지만 나중에 사용합니다. 이 순간 Arrowhead가 시각화되어 라인의 마지막 조인트를 따라갑니다. 화살촉의 회전이 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) ; 
    } 
} 

누군가이 문제를 해결할 수 있도록 도와 줄 수 있습니까?

편집 : 코드에 추가 된 추가 화살촉

답변

0

당신은 폴리 라인의 마지막 두 점에서 변형 된 지오메트리 생성하는 바인딩 변환기 사용할 수 있습니다 :

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

나는 내 코드를 편집 했으므로 표시 할 화살촉이 다르다는 것을 잊어 버렸기 때문에 고정 소수점 집계 크기가 없습니다. – Basseytje

+0

화살표 머리 지점을 정의하는 속성을 변환기에 추가 할 수 있습니다. – Clemens

+0

변환기에 속성을 추가하려면 어떻게합니까? – Basseytje