Отражатель.NET является обычным инструментом для этого.
Чарльз Петцольд написал библиотеку для этого в WPF. По крайней мере, логика должна быть перенесена в Silverlight. Он использует полилинии и контуры, и его легко переносить.
Строки со стрелками @ Блог книги Петцольда
- РЕДАКТИРОВАТЬ -
Хорошо, вот еще один способ сделать это:
Создать пользователя control:
<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 -
@ Number8 задал вопрос о том, как изменить пользовательский элемент управления, чтобы заглавные буквы указывали в том же направлении, что и линия.
Измените 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;
}
Вы можете попробовать треугольный колпачок вместо пера; я использовал его для чего-то похожего
http://msdn.microsoft.com/en-us/library/system.windows.media.penlinecap (VS.95) .aspx
Этот простой метод также создает стрелку, и он сработал для меня.
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;
}