using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Media; namespace SamplePreSystem.UI.BaseControls { public class RingProgressBar : FrameworkElement { /// /// 声明并注册一个依赖属性 Progress,用于控制进度条显示的百分比(0 ~ 100)。 /// public static readonly DependencyProperty ProgressProperty = DependencyProperty.Register( nameof(Progress), // 属性名称 typeof(double), // 属性类型 typeof(RingProgressBar), // 所属类型 new FrameworkPropertyMetadata( 0.0, // 默认值 FrameworkPropertyMetadataOptions.AffectsRender // 当值变化时自动触发重绘 )); /// /// Progress 属性包装器,提供进度值的获取和设置。 /// 设置时自动裁剪到 0~100 范围。 /// public double Progress { get => (double)GetValue(ProgressProperty); set => SetValue(ProgressProperty, Math.Max(0, Math.Min(100, value))); } /// /// 重写 OnRender 方法,使用 DrawingContext 绘制控件外观。 /// protected override void OnRender(DrawingContext dc) { double width = ActualWidth; double height = ActualHeight; // 根据控件尺寸计算圆环半径,保留 5 像素边距 double radius = Math.Min(width, height) / 2 - 5; // 圆心位置 Point center = new Point(width / 2, height / 2); // 1. 绘制背景圆环(灰色圆环) dc.DrawEllipse( null, // 无填充 new Pen(Brushes.LightGray, 30), // 使用浅灰色画笔,宽度10 center, // 圆心 radius, radius // 水平半径 & 垂直半径 ); // 2. 计算进度角度(转换为 0~360) double angle = Progress / 100 * 360; // 3. 将角度转换为弧度,-90 是为了从正上方开始绘制 double radians = (angle - 90) * Math.PI / 180; // 4. 圆环起点:圆顶部 Point startPoint = new Point(center.X, center.Y - radius); // 5. 计算终点:根据弧度计算 X/Y Point endPoint = new Point( center.X + radius * Math.Cos(radians), center.Y + radius * Math.Sin(radians) ); // 6. 判断是否需要绘制大角度弧(超过180度) bool isLargeArc = angle > 180; // 7. 创建一个弧线段,从 startPoint 到 endPoint,构成圆环的一部分 PathFigure figure = new PathFigure( startPoint, // 弧线起点 new[] { new ArcSegment( endPoint, // 弧线终点 new Size(radius, radius), // 弧线的X/Y半径 0, // 旋转角度 isLargeArc, // 是否为大角度弧线 SweepDirection.Clockwise, // 顺时针方向 true // 弧线是否可见(用于裁剪,一般设为 true) ) }, false // 图形是否闭合(环形不闭合) ); // 8. 创建 PathGeometry 对象用于绘制 PathGeometry geometry = new PathGeometry(); geometry.Figures.Add(figure); // 9. 绘制进度圆环(蓝色) dc.DrawGeometry( null, // 无填充 new Pen(Brushes.SteelBlue, 30), // 钢蓝色画笔,宽度10 geometry // 绘制路径 ); } /// /// Measure 阶段:建议大小为 100x100。 /// protected override Size MeasureOverride(Size availableSize) => new Size(100, 100); /// /// Arrange 阶段:直接接受布局系统给予的最终大小。 /// protected override Size ArrangeOverride(Size finalSize) => finalSize; } }