下面的代碼可以讓我畫帶箭頭的線: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)中編寫正確的代碼。 –