c# 实现圆形的进度条(ProgressBar)

 更新时间:2021年03月02日 09:31:35   作者:Hello——寻梦者!  
这篇文章主要介绍了c# 如何实现圆形的进度条(ProgressBar),帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下

      在我们实际的工作中可能经常使用到圆形的进度条,但是这是怎么实现的呢?其实这只不过是修改了一下ProgressBar的模板,我们在下面的代码中我们将ProgressBar的Value值绑定到Border的Background上面,并且使用了一个ValueToProcessConverter的转换器进行相应地转换,这里重点介绍一下这个转换器

<ProgressBar Name="pb" Minimum="0" Maximum="100" >
  <ProgressBar.Template>
    <ControlTemplate TargetType="ProgressBar">
     <Border Background="{TemplateBinding Value, Converter={StaticResource ValueToProcessConverter}, ConverterParameter=250}"/>
    </ControlTemplate>
  </ProgressBar.Template>
</ProgressBar>

下面介绍这部分的源码,并做简要的分析:

      首先,获取ProgressBar.Value,然后再获取ConverterParameter=250这个值,通过这两个值就能确定画的圆环的大小和ProgressBar显示的值,然后我们再调用DrawBrush(arg, 100, radius, radius, Thickness)这个函数来进行绘制,具体代码如下:    

private Brush DrawBrush(double value, double maxValue, double radiusX, double radiusY, double thickness)
        {
            DrawingGroup drawingGroup = new DrawingGroup();
            DrawingContext drawingContext = drawingGroup.Open();
            DrawingGeometry(drawingContext, value, maxValue, radiusX, radiusY, thickness);
            DrawingBrush brush = new DrawingBrush(drawingGroup);
            return brush;
        }

   这里需要注意的是绝不能直接实例化 DrawingContext;但可以通过某些方法(例如 DrawingGroup.Open 和 DrawingVisual.RenderOpen)获取绘图上下文。我们这里是使用DrawingGroup.Open的方法来进行相应的绘图,然后在里面调用里DrawingGeometry这个函数,在这个函数中开始绘制一些DrawEllipse和DrawGeometry,在这个函数中我们讲解一下FormattedText 这个类,使用 FormattedText 对象可以绘制多行文本,且可以单独对该文本中的每个字符设置格式。

private void DrawingGeometry(DrawingContext drawingContext, double value, double maxValue, double radiusX, double radiusY, double thickness)
       {
           drawingContext.DrawEllipse(null, new Pen(EllipseBrush, thickness), centerPoint, radiusX, radiusY);
           drawingContext.DrawGeometry(NormalBrush, new Pen(), GetGeometry(value, maxValue, radiusX, radiusY, thickness));
 
           FormattedText formatWords = new FormattedText(percentString, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, SuccessRateTypeface, SuccessRateFontSize, NormalBrush);
           Point startPoint = new Point(centerPoint.X - formatWords.Width / 2, centerPoint.Y - formatWords.Height / 2 - SuccessRateFontCorrectionValue);
           drawingContext.DrawText(formatWords, startPoint);
 
           drawingContext.Close();
       }  
public class ValueToProcessConverter : IValueConverter
    {
        readonly double Thickness = 20;
        private Point centerPoint;
        private double radius;
        readonly SolidColorBrush NormalBrush = new SolidColorBrush(Colors.White);
        readonly SolidColorBrush EllipseBrush = new SolidColorBrush(Color.FromRgb(107, 132, 165));
 
        string percentString;
        private static readonly Typeface SuccessRateTypeface;
        private const int SuccessRateFontSize = 65;
        readonly double SuccessRateFontCorrectionValue = 12;
 
        static ValueToProcessConverter()
        {
            SuccessRateTypeface = new Typeface(new FontFamily("MSYH"), new FontStyle(), new FontWeight(), new FontStretch());
        }
        public ValueToProcessConverter()
        {
 
        }
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value is double && !string.IsNullOrEmpty((string)parameter))
            {
                double arg = (double)value;
                double width = double.Parse((string)parameter);
                radius = width / 2;
                centerPoint = new Point(radius, radius);
                return DrawBrush(arg, 100, radius, radius, Thickness);
            }
            else
            {
                throw new ArgumentException();
            }
        }
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
 
        /// <summary>
        /// 根据角度获取坐标
        /// </summary>
        /// <param name="CenterPoint"></param>
        /// <param name="r"></param>
        /// <param name="angel"></param>
        /// <returns></returns>
        private Point GetPointByAngel(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;
        }
 
        /// <summary>
        /// 根据4个坐标画出扇形
        /// </summary>
        /// <param name="bigFirstPoint"></param>
        /// <param name="bigSecondPoint"></param>
        /// <param name="smallFirstPoint"></param>
        /// <param name="smallSecondPoint"></param>
        /// <param name="bigRadius"></param>
        /// <param name="smallRadius"></param>
        /// <param name="isLargeArc"></param>
        /// <returns></returns>
        private Geometry DrawingArcGeometry(Point bigFirstPoint, Point bigSecondPoint, Point smallFirstPoint, Point smallSecondPoint, double bigRadius, double smallRadius, bool isLargeArc)
        {
            PathFigure pathFigure = new PathFigure { IsClosed = true };
            pathFigure.StartPoint = bigFirstPoint;
            pathFigure.Segments.Add(
              new ArcSegment
              {
                  Point = bigSecondPoint,
                  IsLargeArc = isLargeArc,
                  Size = new Size(bigRadius, bigRadius),
                  SweepDirection = SweepDirection.Clockwise
              });
            pathFigure.Segments.Add(new LineSegment { Point = smallSecondPoint });
            pathFigure.Segments.Add(
             new ArcSegment
             {
                 Point = smallFirstPoint,
                 IsLargeArc = isLargeArc,
                 Size = new Size(smallRadius, smallRadius),
                 SweepDirection = SweepDirection.Counterclockwise
             });
            PathGeometry pathGeometry = new PathGeometry();
            pathGeometry.Figures.Add(pathFigure);
 
            return pathGeometry;
        }
 
        /// <summary>
        /// 根据当前值和最大值获取扇形
        /// </summary>
        /// <param name="value"></param>
        /// <param name="maxValue"></param>
        /// <returns></returns>
        private Geometry GetGeometry(double value, double maxValue, double radiusX, double radiusY, double thickness)
        {
            bool isLargeArc = false;
            double percent = value / maxValue;
            percentString = string.Format("{0}%", Math.Round(percent * 100, 2));
            double angel = percent * 360D;
            if (angel > 180) isLargeArc = true;
            double bigR = radiusX + thickness / 2;
            double smallR = radiusX - thickness / 2;
            Point firstpoint = GetPointByAngel(centerPoint, bigR, 0);
            Point secondpoint = GetPointByAngel(centerPoint, bigR, angel);
            Point thirdpoint = GetPointByAngel(centerPoint, smallR, 0);
            Point fourpoint = GetPointByAngel(centerPoint, smallR, angel);
            return DrawingArcGeometry(firstpoint, secondpoint, thirdpoint, fourpoint, bigR, smallR, isLargeArc);
        }
 
        /// <summary>
        /// 画扇形
        /// </summary>
        /// <param name="drawingContext"></param>
        /// <param name="value"></param>
        /// <param name="maxValue"></param>
        /// <param name="radiusX"></param>
        /// <param name="radiusY"></param>
        /// <param name="thickness"></param>
        private void DrawingGeometry(DrawingContext drawingContext, double value, double maxValue, double radiusX, double radiusY, double thickness)
        {
            drawingContext.DrawEllipse(null, new Pen(EllipseBrush, thickness), centerPoint, radiusX, radiusY);
            drawingContext.DrawGeometry(NormalBrush, new Pen(), GetGeometry(value, maxValue, radiusX, radiusY, thickness));
            FormattedText formatWords = new FormattedText(percentString, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, SuccessRateTypeface, SuccessRateFontSize, NormalBrush);
            Point startPoint = new Point(centerPoint.X - formatWords.Width / 2, centerPoint.Y - formatWords.Height / 2 - SuccessRateFontCorrectionValue);
            drawingContext.DrawText(formatWords, startPoint);
            drawingContext.Close();
        }
 
        /// <summary>
        /// 根据当前值和最大值画出进度条
        /// </summary>
        /// <param name="value"></param>
        /// <param name="maxValue"></param>
        /// <returns></returns>
        private Brush DrawBrush(double value, double maxValue, double radiusX, double radiusY, double thickness)
        {
            DrawingGroup drawingGroup = new DrawingGroup();
            DrawingContext drawingContext = drawingGroup.Open();
            DrawingGeometry(drawingContext, value, maxValue, radiusX, radiusY, thickness);
            DrawingBrush brush = new DrawingBrush(drawingGroup);
            return brush;
        }
 
    }

以上就是c# 实现圆形的进度条(ProgressBar)的详细内容,更多关于c# 实现进度条的资料请关注脚本之家其它相关文章!

相关文章

  • C# Partial:分部方法和分部类代码实例

    C# Partial:分部方法和分部类代码实例

    这篇文章主要介绍了C# Partial:分部方法和分部类代码实例,本文直接给出代码实现,需要的朋友可以参考下
    2015-03-03
  • C#多线程之Thread中Thread.Join()函数用法分析

    C#多线程之Thread中Thread.Join()函数用法分析

    这篇文章主要介绍了C#多线程之Thread中Thread.Join()函数用法,实例分析了Thread.Join()方法的原理与使用技巧,非常具有实用价值,需要的朋友可以参考下
    2015-04-04
  • C#使用SQL DataAdapter数据适配代码实例

    C#使用SQL DataAdapter数据适配代码实例

    今天小编就为大家分享一篇关于C#使用SQL DataAdapter数据适配代码实例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-10-10
  • Visual C#.Net 网络程序开发-Socket篇

    Visual C#.Net 网络程序开发-Socket篇

    Visual C#.Net 网络程序开发-Socket篇...
    2007-03-03
  • C#中Invoke 和 BeginInvoke 的真正涵义

    C#中Invoke 和 BeginInvoke 的真正涵义

    这篇文章主要介绍了C#中Invoke 和 BeginInvoke 的真正涵义,需要的朋友可以参考下
    2014-10-10
  • C#实现俄罗斯方块

    C#实现俄罗斯方块

    这篇文章主要为大家详细介绍了C#实现俄罗斯方块小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-11-11
  • C#从命令行读取参数的方法

    C#从命令行读取参数的方法

    这篇文章主要介绍了C#从命令行读取参数的方法,实例分析了C#命令行读取参数的实现技巧与操作流程,需要的朋友可以参考下
    2015-04-04
  • C#语言主要特性总结

    C#语言主要特性总结

    这篇文章主要介绍了C#语言主要特性总结,本文总结了C#语言的简单、现代、面向对象、类型安全、相互兼容性、可伸缩性和可升级性等几个主要特点,需要的朋友可以参考下
    2015-02-02
  • 使用C#在注册表中保存信息的例子

    使用C#在注册表中保存信息的例子

    最近做的项目需要在注册表中记录一些用户设置,方便在程序下次启动时读取设置,应用上次用户保存的设置,挺简单的
    2014-04-04
  • c# 应用事务的简单实例

    c# 应用事务的简单实例

    这篇文章介绍了c# 应用事务的简单实例,有需要的朋友可以参考一下
    2013-09-09

最新评论