下面的代码可以让我画带箭头的线:WPF定制LineArrow形状旋转
public sealed class LineArrow : Shape
{
#region X1
public double X1
{
get { return (double)GetValue(X1Property); }
set { SetValue(X1Property, value); }
}
// Using a DependencyProperty as the backing store for X1. This enables animation, styling, binding, etc...
public static readonly DependencyProperty X1Property =
DependencyProperty.Register("X1", typeof(double), typeof(LineArrow), new FrameworkPropertyMetadata(0.0,
FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure));
#endregion
#region Y1
public double Y1
{
get { return (double)GetValue(Y1Property); }
set { SetValue(Y1Property, value); }
}
// Using a DependencyProperty as the backing store for Y1. This enables animation, styling, binding, etc...
public static readonly DependencyProperty Y1Property =
DependencyProperty.Register("Y1", typeof(double), typeof(LineArrow), new FrameworkPropertyMetadata(
0.0, FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure));
#endregion
protected override Geometry DefiningGeometry
{
get
{
var lineStart = new Point(X1, Y1);
var lineEnd = new Point(this.ActualWidth, this.ActualHeight);
var lineAngle = Math.Atan2(this.ActualHeight, this.ActualWidth);
RotateTransform rotation = new RotateTransform() { Angle = lineAngle * 180/Math.PI, CenterX = 0.5, CenterY = 0.5 };
TranslateTransform translate = new TranslateTransform(lineEnd.X, lineEnd.Y);
StreamGeometry streamGeometry = new StreamGeometry();
using(StreamGeometryContext geometryContext = streamGeometry.Open())
{
geometryContext.BeginFigure(lineStart, true, true);
geometryContext.LineTo(lineEnd, true, true);
//left arrow
geometryContext.BeginFigure(lineStart, true, true);
geometryContext.PolyLineTo(new List<Point>()
{
rotation.Transform(new Point(0, -15)),
rotation.Transform(new Point(-15, 0)),
rotation.Transform(new Point(0, 15))
}, true, true);
//right arrow
geometryContext.BeginFigure(lineEnd, true, true);
geometryContext.PolyLineTo(new List<Point>()
{
translate.Transform(rotation.Transform(new Point(0, -15))),
translate.Transform(rotation.Transform(new Point(15,0))),
translate.Transform(rotation.Transform(new Point(0, 15)))
}, true, true);
}
streamGeometry.Freeze();
return streamGeometry;
}
}
}
这里是它如何工作:
我怎样才能使箭头维护自己的在旋转时的初始尺寸为15x15,特别是在接近90度180度的角度时?
不应该RotateTransform照顾应用sin到y和cos到x的数学吗? – sam
@sam,我不是wpf的专家,但我碰巧知道所需坐标的公式如何。作为wpf的局外人,我能做的最多的是解释理论背景。这样,我相信你将能够在你喜欢的风格(带或不带RotateTransform)中编写正确的代码。 –