2016-11-21 3 views
0

Je construis donc cette application dans WPF où je trace une ligne avec une pointe de flèche. Le Arrowhead est un Polygon créé dans un dictionnaire de ressources comme indiqué ci-dessous:WPF La rotation du polygone fait pivoter la direction de déplacement

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

Dans le viewmodel je crée le Arrowhead un PointCollection avec sa position en fonction de la position du dernier joint de la ligne. À la fin, la tête de la flèche doit tourner en fonction de l'angle de la ligne, mais c'est pour plus tard. A ce moment, la tête de flèche est visualisée et suit la dernière articulation de la ligne. Cela ne fonctionne que lorsque la rotation de la pointe de la flèche est 0. Lorsque je change la rotation, le mouvement de la pointe de la flèche change également. Ainsi, par exemple quand je mets la rotation à 90 degrés. la pointe de la flèche tourne de 90 degrés, mais lorsque je déplace la ligne vers la gauche, la pointe de la flèche se déplace vers le haut. J'ai essayé de changer le setter RenderTransform en LayoutTransform. Et j'ai utilisé Polygon.Rendertransform et codé en dur un angle. mais rien ne fonctionne.

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

Quelqu'un peut-il m'aider à résoudre ce problème?

Edit: Ajout des pointes de flèches supplémentaires dans le code

Répondre

0

Vous pouvez utiliser un convertisseur de liaison qui crée une géométrie transformé des deux derniers points d'une polyligne:

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

Vous pouvez utiliser le convertisseur comme dans cet exemple simple:

<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

J'ai édité mon code, j'ai oublié de vous dire qu'il y a différentes têtes de flèches à afficher, donc il n'y a pas de taille de pointcollection fixe. – Basseytje

+0

Vous pouvez ajouter une propriété au convertisseur qui définit les points de la tête de flèche. – Clemens

+0

Comment ajouter une propriété au convertisseur? – Basseytje