using System; using System.Windows; using System.Windows.Media; using System.Windows.Shapes; namespace WpfApp2.Controls { public class Arc : Shape { Size _size = Size.Empty; protected override Geometry DefiningGeometry { get { if(_size == Size.Empty) return Geometry.Empty; return GetGeometry(); } } Geometry GetGeometry() { double angle = this.EndAngle - StartAngle; if (angle == 0) return Geometry.Empty; if (Math.Abs(angle) >= 360d) return new EllipseGeometry(new Point(_size.Width / 2, _size.Height / 2), RadiusXNoThickness, RadiusYNoThickness); var path = new PathGeometry(); var figure = new PathFigure(); path.Figures.Add(figure); var arc = new ArcSegment(); figure.Segments.Add(arc); arc.IsLargeArc = Math.Abs(EndAngle) > 180 || Math.Abs(EndAngle - StartAngle) > 180; arc.SweepDirection = EndAngle > StartAngle ? SweepDirection.Counterclockwise : SweepDirection.Clockwise; arc.Size = new Size(RadiusXNoThickness, RadiusYNoThickness); arc.Point = GetPoint(EndAngle); figure.StartPoint = GetPoint(StartAngle); if (IsStartCenter) { figure.Segments.Insert(0, new LineSegment(figure.StartPoint, true)); figure.StartPoint = new Point(_size.Width / 2, _size.Height / 2); } if(IsClosed) figure.IsClosed = true; return path; } Point GetPoint(double angle) { double d = angle / 180 * Math.PI; double a = RadiusXNoThickness, b = RadiusYNoThickness; double t = a * b / Math.Sqrt(Math.Pow(a * Math.Sin(d), 2) + Math.Pow(b * Math.Cos(d), 2)); double x = t * Math.Cos(d); double y = t * Math.Sin(d); var endPoint = new Point(x + a + (StrokeThickness / 2), b - y + (StrokeThickness / 2)); return endPoint; } protected override Size MeasureOverride(Size constraint) { _size = constraint; return base.MeasureOverride(constraint); } protected override Size ArrangeOverride(Size finalSize) { _size = finalSize; return base.ArrangeOverride(finalSize); } double RadiusXNoThickness => Math.Max(_size.Width / 2 - StrokeThickness / 2, 0); double RadiusYNoThickness => Math.Max(_size.Height / 2 - StrokeThickness / 2, 0); /// <summary> /// 起始点角度 /// </summary> public double StartAngle { get { return (double)GetValue(StartAngleProperty); } set { SetValue(StartAngleProperty, value); } } public static readonly DependencyProperty StartAngleProperty = DependencyProperty.Register("StartAngle", typeof(double), typeof(Arc), new FrameworkPropertyMetadata(0d, FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsRender)); /// <summary> /// 终点角度 /// </summary> public double EndAngle { get { return (double)GetValue(EndAngleProperty); } set { SetValue(EndAngleProperty, value); } } public static readonly DependencyProperty EndAngleProperty = DependencyProperty.Register("EndAngle", typeof(double), typeof(Arc), new FrameworkPropertyMetadata(0d, FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsRender)); /// <summary> /// 是否从椭圆中心开始画线 /// </summary> public bool IsStartCenter { get { return (bool)GetValue(IsStartCenterProperty); } set { SetValue(IsStartCenterProperty, value); } } public static readonly DependencyProperty IsStartCenterProperty = DependencyProperty.Register("IsStartCenter", typeof(bool), typeof(Arc), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsRender)); /// <summary> /// 是否封闭图形 /// </summary> public bool IsClosed { get { return (bool)GetValue(IsClosedProperty); } set { SetValue(IsClosedProperty, value); } } public static readonly DependencyProperty IsClosedProperty = DependencyProperty.Register("IsClosed", typeof(bool), typeof(Arc), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsRender)); } }View Code
属性:
StartAngle: 起点角度;
EndAngle: 终点角度;
IsStartCenter:是否从圆心开始画线;
IsClosed:是否封闭;
使用方式:
<control:Arc Width="100" Height="100" StartAngle="110" EndAngle="-45" Stroke="Blue" StrokeThickness="5" IsStartCenter="True" IsClosed="True" Fill="Orange"/>
标签:控件,return,弧线,double,FrameworkPropertyMetadataOptions,new,WPF,Math,size From: https://www.cnblogs.com/RedSky/p/17757458.html