在DrawingVisual上绘制圆形的进度条,类似于IOS系统风格。

时间:2022-04-27 17:02:20

1.说明:在WPF中,文件下载时需要显示下载进度,由于系统自带的条型进度条比较占用空间,改用圆形的进度条,需要在DrawingVisual上呈现。

运行的效果如图:

在DrawingVisual上绘制圆形的进度条,类似于IOS系统风格。

               private Point GetPointOnCir(Point CenterPoint, double r, double angel)
{
Point p = new Point();
p.X = Math.Sin(angel * Math.PI / 180) * r + CenterPoint.X;
p.Y = CenterPoint.Y - Math.Cos(angel * Math.PI / 180) * r;
return p;
}
private Geometry drawingArc(Point bigCirclefirstPoint, Point bigCirclesecondPoint, Point smallCirclefirstPoint, Point smallCirclesecondPoint, double bigCircleRadius, double smallCircleRadius,bool isLargeArc)
{
PathFigure pathFigure = new PathFigure { IsClosed = true };
pathFigure.StartPoint = bigCirclefirstPoint;
pathFigure.Segments.Add(
new ArcSegment
{
Point = bigCirclesecondPoint,
IsLargeArc = isLargeArc,
Size = new Size(bigCircleRadius, bigCircleRadius),
SweepDirection = SweepDirection.Clockwise
});
pathFigure.Segments.Add(new LineSegment { Point = smallCirclesecondPoint });
pathFigure.Segments.Add(
new ArcSegment
{
Point = smallCirclefirstPoint,
IsLargeArc = isLargeArc,
Size = new Size(smallCircleRadius, smallCircleRadius),
SweepDirection = SweepDirection.Counterclockwise
});
PathGeometry pathGeometry = new PathGeometry();
pathGeometry.Figures.Add(pathFigure);
return pathGeometry;
}
//根据已保存的大小和文件总大小来计算下载进度百分比
private Geometry GetGeometry()
{
bool isLargeArc =false;
double percent = double.Parse(Convert.ToString(savedSize)) / double.Parse(Convert.ToString(fileSize));
PercentString = string.Format("{0}%",Math.Round(percent*100,0));
double angel = percent * 360D;
if(angel>180)isLargeArc=true;
//double angel = 45;
double bigR = 16;
double smallR = 13;
Point centerPoint = vl.StartPoint;//new Point(100, 300);
Point firstpoint = GetPointOnCir(centerPoint, bigR, 0);
Point secondpoint = GetPointOnCir(centerPoint, bigR, angel);
Point thirdpoint = GetPointOnCir(centerPoint, smallR, 0);
Point fourpoint = GetPointOnCir(centerPoint, smallR, angel);
return drawingArc(firstp, secondpoint, thirdpoint, fourpoint, bigR, smallR, isLargeArc);
}

画圆形的进度条,实际上是动态画两个同心圆,根据文件保存的百分比来计算画弧形的角度的大小,需要7个参数:大圆的半径bigR 、小圆的半径smallR 、同心圆的圆心centerPoint 、大圆的起始点firstpoint 、大圆的结束点secondpoint 、小圆的起始点thirdpoint、小圆的结束点fourpoint

在DrawingVisual上绘制圆形的进度条,类似于IOS系统风格。

最后需要使用DrawingContext把圆给画出来:

                public Visual drawShape()
{
DrawingVisual drawingWordsVisual = new DrawingVisual();
DrawingContext drawingContext = drawingWordsVisual.RenderOpen();
try
{
if (savedSize != fileSize)
{
                                        drawingContext.DrawEllipse(null, new Pen(Brushes.Gray, 3), vl.StartPoint, 13, 13);
drawingContext.DrawGeometry(vs.VisualBackgroundBrush, vs.VisualFramePen, GetGeometry());
FormattedText formatWords = new FormattedText(PercentString, System.Globalization.CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface(vs.WordsFont.Name), vs.WordsFont.Size, currentStyle.VisualBackgroundBrush);
formatWords.SetFontWeight(FontWeights.Bold);
Point startPoint = new Point(vl.StartPoint.X - formatWords.Width / 2, vl.StartPoint.Y - formatWords.Height / 2);
drawingContext.DrawText(formatWords, startPoint);
}
else
{
drawingContext.DrawEllipse(null, new Pen(Brushes.Green, 3), vl.StartPoint, 16, 16);
FormattedText formatWords = new FormattedText("Open", System.Globalization.CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface(vs.WordsFont.Name), vs.WordsFont.Size, Brushes.Red);
formatWords.SetFontWeight(FontWeights.Bold);
Point startPoint = new Point(vl.StartPoint.X - formatWords.Width / 2, vl.StartPoint.Y - formatWords.Height / 2);
drawingContext.DrawText(formatWords, startPoint);
} }
catch (Exception ex)
{
new SaveExceptionInfo().SaveLogAsTXTInfoex(ex.Message);
}
finally
{
drawingContext.Close();
}
return drawingWordsVisual;
}