我需要在画布中的控件之间绘制一个箭头.目前我正在使用该Line
对象,但它没有办法在该行的末尾绘制一个三角形.
这大致是我需要的:
[TextBox] <----- [Button]
Run Code Online (Sandbox Code Playgroud)
我试图子类化Line
并在最后添加几行但是类是密封的.
你将如何构建一个在X1,Y1和X2,Y2之间绘制箭头的自定义控件?
Charles Petzold在WPF中编写了一个用于执行此操作的库.至少逻辑应该转移到Silverlight.它使用折线和路径,并且应该易于移植.
- 编辑 -
好的 - 这是另一种方法:
创建用户控件:
<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>
Run Code Online (Sandbox Code Playgroud)
使用以下代码:
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
像这样称呼它:
LayoutRoot.Children.Add(new ArrowsAndDaggersUC(new Point(200, 200), new Point(300, 400)));
Run Code Online (Sandbox Code Playgroud)
并且你将在每行的末尾有1px笔划线和20px笔划三角形.
- 编辑 -
@ 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>
Run Code Online (Sandbox Code Playgroud)
然后,更改"更新"方法以获取线条的角度并将大写字母旋转到该角度:
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;
}
Run Code Online (Sandbox Code Playgroud)
小智 5
这个简单的方法也创建了一个箭头,它对我有用.
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;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
14512 次 |
最近记录: |