WPF制作了一个环形的进度条,如图,其中主要就是使用Path,然后给新建圆弧,前台Path.Data是不可能的了,要后台新建圆弧,接下来就是相应方法
先给个xaml的例子
<!--起点 起点x,起点y 画椭圆 长轴,短轴 旋转角度 是否是优弧 正角方向绘制 终点x,终点y -->
<Path x:Name="cycleProcess" Data="M50,95 A45,45 0 1 1 95, 45" Stroke="#3CB4E5" StrokeThickness="4">
<Path.RenderTransform>
<RotateTransform x:Name="rotate">
</RotateTransform>
</Path.RenderTransform>
</Path>
首先需要明白一点,圆弧无法打开100%,如果到了100%那就变成了点,所以在数值到了100%的时候需要手动调整为不满100,可以是99.999;
起点确定,终点坐标使用三角函数计算,然后就是判断在第几象限,每个象限加减不同
此处给出刷新方法,可自行参考
private void Update()
{
RangeValue = Max - Min;
//百分比
if(CycleProgressBarValueType == CycleProgressBarValueType.Percentage)
{
valueLabel.Content = ((int)(Value / RangeValue * 1000)) / 10f;
}
//数字模式
else if(CycleProgressBarValueType == CycleProgressBarValueType.Value)
{
valueLabel.Content = Value;
}
showValue = Value;
if (showValue == Max)
showValue = Max - 0.001;
height = Height;
if(double.IsNaN(height))
height = ActualHeight;
width = Width;
if (double.IsNaN(width))
width = ActualWidth;
if (height <= 0) return;
if (width <= 0) return;
rotate.CenterX = height / 2d;
rotate.CenterY = width / 2d;
rotate.Angle = OffValue / 2d;
double value = showValue / RangeValue * (360 - OffValue);
value = value / 180 * Math.PI;
double x = 0;
double y = 0;
double cos = 0;
double sin = 0;
//按照起点算象限 最下方为起点
bool isLargeArc = false;
//左下角
if (value <= Math.PI / 2d)
{
cos = Math.Cos(value);
sin = Math.Sin(value);
x = width / 2d - (width / 2d - 5) * sin;
y = height / 2d + (height / 2d - 5) * cos;
}
//左上角
else if (value <= Math.PI)
{
value -= Math.PI / 2.0;
cos = Math.Cos(value);
sin = Math.Sin(value);
x = width / 2d - (width / 2d - 5) * cos;
y = height / 2d - (height / 2d - 5) * sin;
}
//右上角
else if (value <= Math.PI * 3/2.0)
{
value -= Math.PI;
isLargeArc = true;
cos = Math.Cos(value);
sin = Math.Sin(value);
x = width / 2d + (width / 2d - 5) * sin;
y = height / 2d - (height / 2d - 5) * cos;
}
//右下角
else
{
value -= Math.PI *3 / 2.0;
isLargeArc = true;
cos = Math.Cos(value);
sin = Math.Sin(value);
x = width / 2d + (width / 2d - 5) * cos;
y = height / 2d + (height / 2d - 5) * sin;
}
ArcSegment arcSegment = new ArcSegment(new Point(x,y), new Size(width / 2 - 5, height / 2 - 5), 0,
isLargeArc, SweepDirection.Clockwise, true);
PathSegmentCollection pathSegments = new PathSegmentCollection();
pathSegments.Add(arcSegment);
PathFigure pathFigure = new PathFigure(new Point(width / 2, height - 5), pathSegments, false);
PathFigureCollection pathFigures = new PathFigureCollection();
pathFigures.Add(pathFigure);
PathGeometry pathGeometry = new PathGeometry();
pathGeometry.Figures = pathFigures;
//GeometryGroup geometryGroup = new GeometryGroup();
//geometryGroup.Children.Add(pathGeometry);
cycleProcess.Data = pathGeometry;
}