How to draw an arrow in Silverlight

I need to draw an arrow between the controls in the canvas. I am currently using a Line object, but it has no way to draw a triangle at the end of the line.

This is roughly what I need:

[TextBox] <----- [Button]

I tried to subclass the line and add a couple of lines to the end, but the class is sealed.

How would you build a custom control that draws an arrow between X1, Y1 and X2, Y2?

thanks

+5
source share
4 answers

Charles Petzold wrote the library for this in WPF. Logic should at least be passed on to Silverlight. It uses Polylines and Paths and should be easily portable.

Arrow Lines @ Petzold's Blog

- EDIT -

- :

:

<UserControl x:Class="ArrowsAndDaggersLibrary.ArrowsAndDaggersUC"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Canvas x:Name="LayoutRoot">
        <Line x:Name="Cap" />
        <Line x:Name="Connector" />
        <Line x:Name="Foot" />
    </Canvas>
</UserControl>

:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace ArrowsAndDaggersLibrary
{
    public partial class ArrowsAndDaggersUC : UserControl
    {
        private Point startPoint;
        public Point StartPoint
        {
            get { return startPoint; }
            set
            {
                startPoint = value;
                Update();
            }
        }

        private Point endPoint;
        public Point EndPoint
        {
            get { return endPoint; }
            set { 
                endPoint = value;
                Update();
            }
        }

        public ArrowsAndDaggersUC()
        {
            InitializeComponent();
        }

        public ArrowsAndDaggersUC(Point StartPoint, Point EndPoint)
        {
            InitializeComponent();
            startPoint = StartPoint;
            endPoint = EndPoint;
            Update();
        }

        private void Update()
        {
            //reconfig
            Connector.X1 = startPoint.X;
            Connector.Y1 = startPoint.Y;
            Connector.X2 = endPoint.X;
            Connector.Y2 = endPoint.Y;
            Connector.StrokeThickness = 1;
            Connector.Stroke = new SolidColorBrush(Colors.Black);

            Cap.X1 = startPoint.X;
            Cap.Y1 = startPoint.Y;
            Cap.X2 = startPoint.X;
            Cap.Y2 = startPoint.Y;
            Cap.StrokeStartLineCap = PenLineCap.Triangle;
            Cap.StrokeThickness = 20;
            Cap.Stroke = new SolidColorBrush(Colors.Black);

            Foot.X1 = endPoint.X;
            Foot.Y1 = endPoint.Y;
            Foot.X2 = endPoint.X;
            Foot.Y2 = endPoint.Y;
            Foot.StrokeEndLineCap = PenLineCap.Triangle;
            Foot.StrokeThickness = 20;
            Foot.Stroke = new SolidColorBrush(Colors.Black);
        }
    }
}

:

LayoutRoot.Children.Add(new ArrowsAndDaggersUC(new Point(200, 200), new Point(300, 400)));

1px 20px .

- EDIT -

@ 8 , , , .

Xaml :

<UserControl x:Class="ArrowsAndDaggersLibrary.ArrowsAndDaggersUC"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Canvas x:Name="LayoutRoot">
        <Line x:Name="Cap">
            <Line.RenderTransform>
                <RotateTransform x:Name="CapRotateTransform" />
            </Line.RenderTransform>
        </Line>
        <Line x:Name="Connector" />
        <Line x:Name="Foot">
            <Line.RenderTransform>
                <RotateTransform x:Name="FootRotateTransform" />
            </Line.RenderTransform>
        </Line>
    </Canvas>
</UserControl>

"", :

private void Update()
{

    double angleOfLine = Math.Atan2((endPoint.Y - startPoint.Y), (endPoint.X - startPoint.X)) * 180 / Math.PI;

    Connector.X1 = startPoint.X;
    Connector.Y1 = startPoint.Y;
    Connector.X2 = endPoint.X;
    Connector.Y2 = endPoint.Y;
    Connector.StrokeThickness = 1;
    Connector.Stroke = new SolidColorBrush(Colors.Black);

    Cap.X1 = startPoint.X;
    Cap.Y1 = startPoint.Y;
    Cap.X2 = startPoint.X;
    Cap.Y2 = startPoint.Y;
    Cap.StrokeStartLineCap = PenLineCap.Triangle;
    Cap.StrokeThickness = 20;
    Cap.Stroke = new SolidColorBrush(Colors.Black);

    CapRotateTransform.Angle = angleOfLine;
    CapRotateTransform.CenterX = startPoint.X;
    CapRotateTransform.CenterY = startPoint.Y;

    Foot.X1 = endPoint.X;
    Foot.Y1 = endPoint.Y;
    Foot.X2 = endPoint.X;
    Foot.Y2 = endPoint.Y;
    Foot.StrokeEndLineCap = PenLineCap.Triangle;
    Foot.StrokeThickness = 20;
    Foot.Stroke = new SolidColorBrush(Colors.Black);

    FootRotateTransform.Angle = angleOfLine;
    FootRotateTransform.CenterX = endPoint.X;
    FootRotateTransform.CenterY = endPoint.Y;
}
+7

, .

    private static Shape DrawArrow(Point p1, Point p2)
    {
        GeometryGroup lineGroup = new GeometryGroup();

        double theta = Math.Atan2((p2.Y - p1.Y),(p2.X - p1.X)) * 180 / Math.PI;

        PathGeometry pathGeometry = new PathGeometry();
        PathFigure pathFigure = new PathFigure();
        pathFigure.StartPoint = p1;

        Point lpoint = new Point(p1.X + 2, p1.Y + 10);
        Point rpoint = new Point(p1.X - 2, p1.Y + 10);
        LineSegment seg1 = new LineSegment();
        seg1.Point = lpoint;
        pathFigure.Segments.Add(seg1);

        LineSegment seg2 = new LineSegment();
        seg2.Point = rpoint;
        pathFigure.Segments.Add(seg2);

        LineSegment seg3 = new LineSegment();
        seg3.Point = p1;
        pathFigure.Segments.Add(seg3);

        pathGeometry.Figures.Add(pathFigure);
        RotateTransform transform = new RotateTransform();
        transform.Angle = theta - 90;
        transform.CenterX = p1.X;
        transform.CenterY = p1.Y;
        pathGeometry.Transform = transform;
        lineGroup.Children.Add(pathGeometry);

        LineGeometry connectorGeometry = new LineGeometry();
        connectorGeometry.StartPoint = p1;
        connectorGeometry.EndPoint = p2;
        lineGroup.Children.Add(connectorGeometry);
        Path path = new Path();
        path.Data = lineGroup;
        return path;
    }
+5

Runtime

//animation
public class Cls_Barriere
    {                       
        // animazione periferica
        public static void LineAnimation(Line _line,String _colore)
        {

            Storyboard result = new Storyboard();
            Duration duration = new Duration(TimeSpan.FromSeconds(2));

            ColorAnimation animation = new ColorAnimation();
            animation.RepeatBehavior = RepeatBehavior.Forever;
            animation.Duration = duration;
            switch (_colore.ToUpper())
            {
                case "RED": 
                    animation.From = Colors.Red;
                    break;
                case "ORANGE": 
                    animation.From = Colors.Orange;
                    break;
                case "YELLOW": 
                    animation.From = Colors.Yellow;
                    break;
                case "GRAY": 
                    animation.From = Colors.DarkGray;
                    break;
                default: 
                    animation.From = Colors.Green;
                    break;
            }

            animation.To = Colors.Gray;
            Storyboard.SetTarget(animation, _line);
            Storyboard.SetTargetProperty(animation, new PropertyPath("(Line.Stroke).(SolidColorBrush.Color)"));
            result.Children.Add(animation);
            result.Begin();

        }
    }



public partial class MainPage : UserControl
    {
        private Point startPoint;
        private Point endPoint;

        // canvas event onmouse click to start drawing runtime a line
        public MainPage()
        {
            InitializeComponent();
            Canvas.MouseLeftButtonDown += Canvas_MouseLeftButtonDown;
            Canvas.MouseLeftButtonUp += Canvas_MouseLeftButtonUp;

        }

        // on muose up drawing line and add canvas all references
        void Canvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            endPoint = new Point();
            endPoint.X = e.GetPosition(this.Canvas).X;
            endPoint.Y = e.GetPosition(this.Canvas).Y;
            Line LineCap = new Line();
            Line LineFoot = new Line();
            Line LineConnect = new Line();
            RotateTransform FootRotateTransform = new RotateTransform();
            RotateTransform CapRotateTransform = new RotateTransform();


            LineConnect.Stroke = new SolidColorBrush(Colors.White);
            LineConnect.StrokeThickness = 5;
            LineConnect.StrokeStartLineCap = PenLineCap.Round;
            LineConnect.StrokeEndLineCap = PenLineCap.Round;
            LineConnect.X1 = startPoint.X;
            LineConnect.Y1 = startPoint.Y;
            LineConnect.X2 = endPoint.X;
            LineConnect.Y2 = endPoint.Y;

            LineCap.X1 = startPoint.X;
            LineCap.X2 = startPoint.X;
            LineCap.Y1 = startPoint.Y;
            LineCap.Y2 = startPoint.Y;
            LineCap.StrokeThickness = 20;
            LineCap.StrokeStartLineCap = PenLineCap.Round;
            LineCap.Stroke = new SolidColorBrush(Colors.White);
            LineFoot.StrokeThickness = 20;

            LineFoot.X1 = endPoint.X;
            LineFoot.X2 = endPoint.X;
            LineFoot.Y1 = endPoint.Y;
            LineFoot.Y2 = endPoint.Y;
            LineFoot.StrokeEndLineCap = PenLineCap.Triangle;
            LineFoot.Stroke = new SolidColorBrush(Colors.White);
            Double angleOfLine = new Double();
            angleOfLine = Math.Atan2((LineConnect.Y2 - LineConnect.Y1), (LineConnect.X2 - LineConnect.X1)) * 180 / Math.PI;
            FootRotateTransform.Angle = angleOfLine;
            FootRotateTransform.CenterX = endPoint.X;
            FootRotateTransform.CenterY = endPoint.Y;

            CapRotateTransform.Angle = angleOfLine;
            CapRotateTransform.CenterX = startPoint.X;
            CapRotateTransform.CenterY = startPoint.Y;
            LineFoot.RenderTransform = FootRotateTransform;
            LineCap.RenderTransform = CapRotateTransform;

            LineConnect.Loaded += _line_Loaded;
            LineCap.Loaded += _line_Loaded;
            LineFoot.Loaded += _line_Loaded;
            Canvas.Children.Add(LineConnect);
            Canvas.Children.Add(LineCap);
            Canvas.Children.Add(LineFoot);
        }
        //load animation color
        void _line_Loaded(object sender, RoutedEventArgs e)
        {
            Cls_Barriere.LineAnimation(sender as Line, "RED");
        }
        // add canvas lines
        void Canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            startPoint = new Point();
            startPoint.X = e.GetPosition(this.Canvas).X;
            startPoint.Y = e.GetPosition(this.Canvas).Y;
        }



    }
0

All Articles