Charles Petzold đã viết một thư viện để làm điều này trong WPF. Logic, ít nhất, nên được chuyển giao cho Silverlight. Nó sử dụng Polylines và Paths và nên dễ dàng để port.
Lines with Arrows @ Petzold Book Blog
--EDIT--
Ok - đây là một cách khác để đi về nó:
Tạo một điều khiển người dùng:
<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>
như sau mã:
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);
}
}
}
Gọi nó như thế này:
LayoutRoot.Children.Add(new ArrowsAndDaggersUC(new Point(200, 200), new Point(300, 400)));
và bạn sẽ có dòng đột quỵ 1px với tam giác đột quỵ 20px ở đầu của mỗi dòng.
--EDIT--
@ Number8 có một câu hỏi về cách sửa đổi các điều khiển người dùng để các mũ sẽ chỉ theo hướng tương tự như các dòng.
Sửa đổi XAML của điều khiển người dùng như vậy:
<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>
Sau đó, thay đổi "Cập nhật" phương pháp để có được những góc của đường và xoay nắp để góc rằng:
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;
}
Đó là một số mã thú vị nhưng trong Silverlight tôi không thể kế thừa từ Line (hoặc hình dạng cho vấn đề đó) như Petzold đã làm trong WPF.Dòng được niêm phong và hình dạng không làm bất kỳ bản vẽ nào. Tôi nghĩ rằng thời gian chạy chịu trách nhiệm vẽ bởi vì mỗi lớp Shape có một "định danh được biết đến" khác nhau. –
Ví dụ thứ hai hoạt động. Cảm ơn. –
Công việc hay. Có vẻ như các mũi tên chỉ hướng đông-tây, ngay cả khi dòng chạy nw-se. Nó sẽ làm gì để làm cho các đầu mũi tên hướng cùng một hướng đường đang chạy? – Number8