如何创建圆形样式进度条

问题描述 投票:0回答:5

我需要帮助来实现这样的圆形进度条:

CircularProgressbar

如何通过增加

Value
属性来实现圆填充?

c# wpf user-controls progress-bar
5个回答
23
投票

您有几个选项 - 第一个是模板化

ProgressBar
控件。事实证明这有点棘手。我写了一篇博文,描述了如何使用附加的 ViewModel 来实现所需的效果

另一种选择是从头开始创建您自己的控件。您可以执行以下操作:

  1. 创建新的用户控件
  2. 向其添加新的值、最大和最小依赖属性。
  3. 处理用户控件中的值、最大值和最小值属性更改事件以计算角度属性。
  4. 在后面的代码中构造两个“饼图”(参见这篇文章)并将它们添加到 UI。

21
投票

我知道这是一个老问题,但无论如何这是我的解决方案:

对于WINFORM:

using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

public class CircularProgressBar : Control
{
    #region Enums

    public enum _ProgressShape
    {
        Round,
        Flat
    }

    public enum _TextMode
    {
        None,
        Value,
        Percentage,
        Custom
    }

    #endregion

    #region Private Variables

    private long _Value;
    private long _Maximum = 100;
    private int _LineWitdh = 1;
    private float _BarWidth = 14f;

    private Color _ProgressColor1 = Color.Orange;
    private Color _ProgressColor2 = Color.Orange;
    private Color _LineColor = Color.Silver;
    private LinearGradientMode _GradientMode = LinearGradientMode.ForwardDiagonal;
    private _ProgressShape ProgressShapeVal;
    private _TextMode ProgressTextMode;

    #endregion

    #region Contructor

    public CircularProgressBar()
    {
        SetStyle(ControlStyles.SupportsTransparentBackColor, true);
        SetStyle(ControlStyles.Opaque, true);
        this.BackColor = SystemColors.Control;
        this.ForeColor = Color.DimGray;

        this.Size = new Size(130, 130);
        this.Font = new Font("Segoe UI", 15);
        this.MinimumSize = new Size(100, 100);
        this.DoubleBuffered = true;

        this.LineWidth = 1;
        this.LineColor = Color.DimGray;

        Value = 57;
        ProgressShape = _ProgressShape.Flat;
        TextMode = _TextMode.Percentage;
    }

    #endregion

    #region Public Custom Properties

    /// <summary>Determina el Valor del Progreso</summary>
    [Description("Valor Entero que determina la posision de la Barra de Progreso."), Category("Behavior")]
    public long Value
    {
        get { return _Value; }
        set
        {
            if (value > _Maximum)
                value = _Maximum;
            _Value = value;
            Invalidate();
        }
    }

    [Description("Obtiene o Establece el Valor Maximo de la barra de Progreso."), Category("Behavior")]
    public long Maximum
    {
        get { return _Maximum; }
        set
        {
            if (value < 1)
                value = 1;
            _Maximum = value;
            Invalidate();
        }
    }

    [Description("Color Inicial de la Barra de Progreso"), Category("Appearance")]
    public Color BarColor1
    {
        get { return _ProgressColor1; }
        set
        {
            _ProgressColor1 = value;
            Invalidate();
        }
    }

    [Description("Color Final de la Barra de Progreso"), Category("Appearance")]
    public Color BarColor2
    {
        get { return _ProgressColor2; }
        set
        {
            _ProgressColor2 = value;
            Invalidate();
        }
    }

    [Description("Ancho de la Barra de Progreso"), Category("Appearance")]
    public float BarWidth
    {
        get { return _BarWidth; }
        set
        {
            _BarWidth = value;
            Invalidate();
        }
    }

    [Description("Modo del Gradiente de Color"), Category("Appearance")]
    public LinearGradientMode GradientMode
    {
        get { return _GradientMode; }
        set
        {
            _GradientMode = value;
            Invalidate();
        }
    }

    [Description("Color de la Linea Intermedia"), Category("Appearance")]
    public Color LineColor
    {
        get { return _LineColor; }
        set
        {
            _LineColor = value;
            Invalidate();
        }
    }

    [Description("Ancho de la Linea Intermedia"), Category("Appearance")]
    public int LineWidth
    {
        get { return _LineWitdh; }
        set
        {
            _LineWitdh = value;
            Invalidate();
        }
    }

    [Description("Obtiene o Establece la Forma de los terminales de la barra de progreso."), Category("Appearance")]
    public _ProgressShape ProgressShape
    {
        get { return ProgressShapeVal; }
        set
        {
            ProgressShapeVal = value;
            Invalidate();
        }
    }

    [Description("Obtiene o Establece el Modo como se muestra el Texto dentro de la barra de Progreso."), Category("Behavior")]
    public _TextMode TextMode
    {
        get { return ProgressTextMode; }
        set
        {
            ProgressTextMode = value;
            Invalidate();
        }
    }

    [Description("Obtiene el Texto que se muestra dentro del Control"), Category("Behavior")]
    public override string Text { get; set; }

    #endregion

    #region EventArgs

    protected override void OnResize(EventArgs e)
    {
        base.OnResize(e);
        SetStandardSize();
    }

    protected override void OnSizeChanged(EventArgs e)
    {
        base.OnSizeChanged(e);
        SetStandardSize();
    }

    protected override void OnPaintBackground(PaintEventArgs p)
    {
        base.OnPaintBackground(p);
    }

    #endregion

    #region Methods

    private void SetStandardSize()
    {
        int _Size = Math.Max(Width, Height);
        Size = new Size(_Size, _Size);
    }

    public void Increment(int Val)
    {
        this._Value += Val;
        Invalidate();
    }

    public void Decrement(int Val)
    {
        this._Value -= Val;
        Invalidate();
    }
    #endregion

    #region Events

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        using (Bitmap bitmap = new Bitmap(this.Width, this.Height))
        {
            using (Graphics graphics = Graphics.FromImage(bitmap))
            {
                graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
                graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
                graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

                //graphics.Clear(Color.Transparent); //<-- this.BackColor, SystemColors.Control, Color.Transparent

                PaintTransparentBackground(this, e);

                //Dibuja el circulo blanco interior:
                using (Brush mBackColor = new SolidBrush(this.BackColor))
                {
                    graphics.FillEllipse(mBackColor,
                            18, 18,
                            (this.Width - 0x30) + 12,
                            (this.Height - 0x30) + 12);
                }
                // Dibuja la delgada Linea gris del medio:
                using (Pen pen2 = new Pen(LineColor, this.LineWidth))
                {
                    graphics.DrawEllipse(pen2, 
                        18, 18,
                      (this.Width - 0x30) + 12, 
                      (this.Height - 0x30) + 12);
                }

                //Dibuja la Barra de Progreso
                using (LinearGradientBrush brush = new LinearGradientBrush(this.ClientRectangle, 
                    this._ProgressColor1, this._ProgressColor2, this.GradientMode))
                {
                    using (Pen pen = new Pen(brush, this.BarWidth))
                    {
                        switch (this.ProgressShapeVal)
                        {
                            case _ProgressShape.Round:
                                pen.StartCap = LineCap.Round;
                                pen.EndCap = LineCap.Round;
                                break;

                            case _ProgressShape.Flat:
                                pen.StartCap = LineCap.Flat;
                                pen.EndCap = LineCap.Flat;
                                break;
                        }

                        //Aqui se dibuja realmente la Barra de Progreso
                        graphics.DrawArc(pen, 
                            0x12, 0x12,
                            (this.Width - 0x23) - 2, 
                            (this.Height - 0x23) - 2, 
                            -90, 
                            (int)Math.Round((double)((360.0 / ((double)this._Maximum)) * this._Value)));
                    }
                }

                #region Dibuja el Texto de Progreso

                switch (this.TextMode)
                {
                    case _TextMode.None:
                        this.Text = string.Empty;
                        break;

                    case _TextMode.Value:
                        this.Text = _Value.ToString();
                        break;

                    case _TextMode.Percentage:
                        this.Text = Convert.ToString(Convert.ToInt32((100 / _Maximum) * _Value));
                        break;

                    default:
                        break;
                }

                if (this.Text != string.Empty)
                {
                    using (Brush FontColor = new SolidBrush(this.ForeColor))
                    {
                        int ShadowOffset = 2;
                        SizeF MS = graphics.MeasureString(this.Text, this.Font);
                        SolidBrush shadowBrush = new SolidBrush(Color.FromArgb(100, this.ForeColor));

                        //Sombra del Texto:
                        graphics.DrawString(this.Text, this.Font, shadowBrush,
                            Convert.ToInt32(Width / 2 - MS.Width / 2) + ShadowOffset,
                            Convert.ToInt32(Height / 2 - MS.Height / 2) + ShadowOffset
                        );

                        //Texto del Control:
                        graphics.DrawString(this.Text, this.Font, FontColor,
                            Convert.ToInt32(Width / 2 - MS.Width / 2),
                            Convert.ToInt32(Height / 2 - MS.Height / 2));
                    }
                }

                #endregion

                //Aqui se Dibuja todo el Control:
                e.Graphics.DrawImage(bitmap, 0, 0);
                graphics.Dispose();
                bitmap.Dispose();
            }
        }
    }

    private static void PaintTransparentBackground(Control c, PaintEventArgs e)
    {
        if (c.Parent == null || !Application.RenderWithVisualStyles)
            return;

        ButtonRenderer.DrawParentBackground(e.Graphics, c.ClientRectangle, c);
    }

    /// <summary>Dibuja un Circulo Relleno de Color con los Bordes perfectos.</summary>
    /// <param name="g">'Canvas' del Objeto donde se va a dibujar</param>
    /// <param name="brush">Color y estilo del relleno</param>
    /// <param name="centerX">Centro del Circulo, en el eje X</param>
    /// <param name="centerY">Centro del Circulo, en el eje Y</param>
    /// <param name="radius">Radio del Circulo</param>
    private void FillCircle(Graphics g, Brush brush, float centerX, float centerY, float radius)
    {
        g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
        g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
        g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
        g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

        using (System.Drawing.Drawing2D.GraphicsPath gp = new System.Drawing.Drawing2D.GraphicsPath())
        {
            g.FillEllipse(brush, centerX - radius, centerY - radius,
                      radius + radius, radius + radius);
        }
    }

    #endregion
}

实施:

  1. 将源代码放入 WinForms 项目中任意位置的新类中,将该类命名为“CircularProgressBar.cs”。
  2. 编译项目。
  3. 编译后,您应该在工具栏上看到一个新的控件或“组件”。
  4. 将此新控件拖放到任何表单中并自定义其属性。

控制看起来像这样:

享受吧。


16
投票

这有点棘手,但并非不可能。这是我使用平滑动画进行指导的实现。应该使用值转换器来创建 CircularProgressBar。

CircularProgressBar.cs

 public partial class CircularProgressBar : ProgressBar
{
    public CircularProgressBar()
    {
        this.ValueChanged += CircularProgressBar_ValueChanged;
    }

    void CircularProgressBar_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
    {
        CircularProgressBar bar = sender as CircularProgressBar;
        double currentAngle = bar.Angle;
        double targetAngle = e.NewValue / bar.Maximum * 359.999;

        DoubleAnimation anim = new DoubleAnimation(currentAngle, targetAngle, TimeSpan.FromMilliseconds(500));
        bar.BeginAnimation(CircularProgressBar.AngleProperty, anim, HandoffBehavior.SnapshotAndReplace);
    }

    public double Angle
    {
        get { return (double)GetValue(AngleProperty); }
        set { SetValue(AngleProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Angle.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty AngleProperty =
        DependencyProperty.Register("Angle", typeof(double), typeof(CircularProgressBar), new PropertyMetadata(0.0));

    public double StrokeThickness
    {
        get { return (double)GetValue(StrokeThicknessProperty); }
        set { SetValue(StrokeThicknessProperty, value); }
    }

    // Using a DependencyProperty as the backing store for StrokeThickness.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty StrokeThicknessProperty =
        DependencyProperty.Register("StrokeThickness", typeof(double), typeof(CircularProgressBar), new PropertyMetadata(10.0));
}

AngleToPointConverter.cs

class AngleToPointConverter : IValueConverter
{

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        double angle = (double)value;
        double radius = 50;
        double piang = angle * Math.PI / 180;

        double px = Math.Sin(piang) * radius + radius;
        double py = -Math.Cos(piang) * radius + radius;

        return new Point(px, py);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

AngleToIsLargeConverter.cs

class AngleToIsLargeConverter : IValueConverter
{

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        double angle = (double)value;

        return angle > 180;
    }

    public object ConvertBack(object value, Type targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

应用程序.xaml

<Application x:Class="WpfApplication1.App"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         StartupUri="MainWindow.xaml"
         xmlns:my="clr-namespace:WpfApplication1">
<Application.Resources>
    <my:AngleToPointConverter x:Key="prConverter"/>
    <my:AngleToIsLargeConverter x:Key="isLargeConverter"/>

    <Style x:Key="circularProgressBar" TargetType="my:CircularProgressBar">
        <Setter Property="Value" Value="10"/>
        <Setter Property="Maximum" Value="100"/>
        <Setter Property="StrokeThickness" Value="10"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="my:CircularProgressBar">
                        <Canvas Width="100" Height="100">
                        <Ellipse Width="100" Height="100" Stroke="LightGray"
                                     StrokeThickness="1"/>

                        <Path Stroke="{TemplateBinding Background}" 
                                  StrokeThickness="{TemplateBinding StrokeThickness}">
                                <Path.Data>
                                    <PathGeometry>
                                        <PathFigure x:Name="fig" StartPoint="50,0">
                                            <ArcSegment RotationAngle="0" SweepDirection="Clockwise"
                                                        Size="50,50"
                                                        Point="{Binding Path=Angle, Converter={StaticResource prConverter}, RelativeSource={RelativeSource FindAncestor, AncestorType=ProgressBar}}"
                                                        IsLargeArc="{Binding Path=Angle, Converter={StaticResource isLargeConverter}, RelativeSource={RelativeSource FindAncestor, AncestorType=ProgressBar}}"
                                                        >
                                            </ArcSegment>
                                        </PathFigure>
                                    </PathGeometry>
                                </Path.Data>
                            </Path>
                            <Border Width="100" Height="100">
                                <TextBlock Foreground="Gray" HorizontalAlignment="Center" VerticalAlignment="Center"
                                       Text="{Binding Path=Value, StringFormat={}%{0}, 
                                RelativeSource={RelativeSource TemplatedParent}}"
                                           FontSize="{TemplateBinding FontSize}"/>
                            </Border>
                        </Canvas>

                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Application.Resources>

可以通过添加更多属性(例如 InnerRadius、Radius 等)来进行更多自定义


6
投票

你看过

ValueConverter
吗?您可以使用
TemplateBinding
绑定到模板中的 Value 属性,并使用适当的值转换器将值更改为对圆形进度条有用的值。

编辑:

在模板中:

  1. 添加一个圆圈,填充黄色。

  2. 在顶部添加另一个圆圈,颜色为橙色。

  3. 使用值转换器(或多值转换器)返回 2 中添加的圆的裁剪几何图形(可能使用圆弧段)。

  4. 在 2 中剪裁圆,并在 3 中返回几何图形。

  5. 投反对票的人还给我我的代表。


0
投票
    using System;
    using System.ComponentModel;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Windows.Forms;


namespace Your Namespace
{
    public class CircularProgressBar : Control
    {
        #region Enums

        public enum _ProgressShape
        {
            Round,
            Flat
        }

        public enum _TextMode
        {
            None,
            Value,
            Percentage,
            Custom
        }

        #endregion

        #region Private Variables

        private long _Value;
        private long _Maximum = 100;
        private int _LineWitdh = 1;
        private float _BarWidth = 14f;

        private Color _ProgressColor1 = Color.Orange;
        private Color _ProgressColor2 = Color.Orange;
        private Color _LineColor = Color.Silver;
        private LinearGradientMode _GradientMode = LinearGradientMode.ForwardDiagonal;
        private _ProgressShape ProgressShapeVal;
        private _TextMode ProgressTextMode;

        #endregion

        #region Contructor

        public CircularProgressBar()
        {
            SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            SetStyle(ControlStyles.Opaque, true);
            this.BackColor = SystemColors.Control;
            this.ForeColor = Color.DimGray;

            this.Size = new Size(130, 130);
            this.Font = new Font("Segoe UI", 15);
            this.MinimumSize = new Size(100, 100);
            this.DoubleBuffered = true;

            this.LineWidth = 1;
            this.LineColor = Color.DimGray;

            Value = 57;
            ProgressShape = _ProgressShape.Flat;
            TextMode = _TextMode.Percentage;
        }

        #endregion

        #region Public Custom Properties

        /// <summary>Determina el Valor del Progreso</summary>
        [Description("Valor Entero que determina la posision de la Barra de Progreso."), Category("Behavior")]
        public long Value
        {
            get { return _Value; }
            set
            {
                if (value > _Maximum)
                    value = _Maximum;
                _Value = value;
                Invalidate();
            }
        }

        [Description("Obtiene o Establece el Valor Maximo de la barra de Progreso."), Category("Behavior")]
        public long Maximum
        {
            get { return _Maximum; }
            set
            {
                if (value < 1)
                    value = 1;
                _Maximum = value;
                Invalidate();
            }
        }

        [Description("Color Inicial de la Barra de Progreso"), Category("Appearance")]
        public Color BarColor1
        {
            get { return _ProgressColor1; }
            set
            {
                _ProgressColor1 = value;
                Invalidate();
            }
        }

        [Description("Color Final de la Barra de Progreso"), Category("Appearance")]
        public Color BarColor2
        {
            get { return _ProgressColor2; }
            set
            {
                _ProgressColor2 = value;
                Invalidate();
            }
        }

        [Description("Ancho de la Barra de Progreso"), Category("Appearance")]
        public float BarWidth
        {
            get { return _BarWidth; }
            set
            {
                _BarWidth = value;
                Invalidate();
            }
        }

        [Description("Modo del Gradiente de Color"), Category("Appearance")]
        public LinearGradientMode GradientMode
        {
            get { return _GradientMode; }
            set
            {
                _GradientMode = value;
                Invalidate();
            }
        }

        [Description("Color de la Linea Intermedia"), Category("Appearance")]
        public Color LineColor
        {
            get { return _LineColor; }
            set
            {
                _LineColor = value;
                Invalidate();
            }
        }

        [Description("Ancho de la Linea Intermedia"), Category("Appearance")]
        public int LineWidth
        {
            get { return _LineWitdh; }
            set
            {
                _LineWitdh = value;
                Invalidate();
            }
        }

        [Description("Obtiene o Establece la Forma de los terminales de la barra de progreso."), Category("Appearance")]
        public _ProgressShape ProgressShape
        {
            get { return ProgressShapeVal; }
            set
            {
                ProgressShapeVal = value;
                Invalidate();
            }
        }

        [Description("Obtiene o Establece el Modo como se muestra el Texto dentro de la barra de Progreso."), Category("Behavior")]
        public _TextMode TextMode
        {
            get { return ProgressTextMode; }
            set
            {
                ProgressTextMode = value;
                Invalidate();
            }
        }

        [Description("Obtiene el Texto que se muestra dentro del Control"), Category("Behavior")]
        public override string Text { get; set; }

        #endregion

        #region EventArgs

        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            SetStandardSize();
        }

        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);
            SetStandardSize();
        }

        protected override void OnPaintBackground(PaintEventArgs p)
        {
            base.OnPaintBackground(p);
        }

        #endregion

        #region Methods

        private void SetStandardSize()
        {
            int _Size = Math.Max(Width, Height);
            Size = new Size(_Size, _Size);
        }

        public void Increment(int Val)
        {
            this._Value += Val;
            Invalidate();
        }

        public void Decrement(int Val)
        {
            this._Value -= Val;
            Invalidate();
        }
        #endregion

        #region Events

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            using (Bitmap bitmap = new Bitmap(this.Width, this.Height))
            {
                using (Graphics graphics = Graphics.FromImage(bitmap))
                {
                    graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
                    graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                    graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
                    graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

                    //graphics.Clear(Color.Transparent); //<-- this.BackColor, SystemColors.Control, Color.Transparent

                    PaintTransparentBackground(this, e);

                    //Dibuja el circulo blanco interior:
                    using (Brush mBackColor = new SolidBrush(this.BackColor))
                    {
                        graphics.FillEllipse(mBackColor,
                                18, 18,
                                (this.Width - 0x30) + 12,
                                (this.Height - 0x30) + 12);
                    }
                    // Dibuja la delgada Linea gris del medio:
                    using (Pen pen2 = new Pen(LineColor, this.LineWidth))
                    {
                        graphics.DrawEllipse(pen2,
                            18, 18,
                          (this.Width - 0x30) + 12,
                          (this.Height - 0x30) + 12);
                    }

                    //Dibuja la Barra de Progreso
                    using (LinearGradientBrush brush = new LinearGradientBrush(this.ClientRectangle,
                        this._ProgressColor1, this._ProgressColor2, this.GradientMode))
                    {
                        using (Pen pen = new Pen(brush, this.BarWidth))
                        {
                            switch (this.ProgressShapeVal)
                            {
                                case _ProgressShape.Round:
                                    pen.StartCap = LineCap.Round;
                                    pen.EndCap = LineCap.Round;
                                    break;

                                case _ProgressShape.Flat:
                                    pen.StartCap = LineCap.Flat;
                                    pen.EndCap = LineCap.Flat;
                                    break;
                            }

                            //Aqui se dibuja realmente la Barra de Progreso
                            graphics.DrawArc(pen,
                                0x12, 0x12,
                                (this.Width - 0x23) - 2,
                                (this.Height - 0x23) - 2,
                                -90,
                                (int)Math.Round((double)((360.0 / ((double)this._Maximum)) * this._Value)));
                        }
                    }

                    #region Dibuja el Texto de Progreso

                    string percentageText = Convert.ToString(Convert.ToInt32((100 / _Maximum) * _Value)) + "%";
                    using (Brush FontColor = new SolidBrush(this.ForeColor))
                    {
                        SizeF MS = graphics.MeasureString(percentageText, this.Font);
                        SolidBrush shadowBrush = new SolidBrush(Color.FromArgb(100, this.ForeColor));

                        // Sombra del Texto:
                        graphics.DrawString(percentageText, this.Font, shadowBrush,
                            Convert.ToInt32(Width / 2 - MS.Width / 2) + 2,
                            Convert.ToInt32(Height / 2 - MS.Height / 2) + 2
                        );

                        // Texto del Control:
                        graphics.DrawString(percentageText, this.Font, FontColor,
                            Convert.ToInt32(Width / 2 - MS.Width / 2),
                            Convert.ToInt32(Height / 2 - MS.Height / 2));
                    }

                    #endregion


                    //Aqui se Dibuja todo el Control:
                    e.Graphics.DrawImage(bitmap, 0, 0);
                    graphics.Dispose();
                    bitmap.Dispose();
                }
            }
        }

        private static void PaintTransparentBackground(Control c, PaintEventArgs e)
        {
            if (c.Parent == null || !Application.RenderWithVisualStyles)
                return;

            ButtonRenderer.DrawParentBackground(e.Graphics, c.ClientRectangle, c);
        }

        /// <summary>Dibuja un Circulo Relleno de Color con los Bordes perfectos.</summary>
        /// <param name="g">'Canvas' del Objeto donde se va a dibujar</param>
        /// <param name="brush">Color y estilo del relleno</param>
        /// <param name="centerX">Centro del Circulo, en el eje X</param>
        /// <param name="centerY">Centro del Circulo, en el eje Y</param>
        /// <param name="radius">Radio del Circulo</param>
        private void FillCircle(Graphics g, Brush brush, float centerX, float centerY, float radius)
        {
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
            g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
            g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

            using (System.Drawing.Drawing2D.GraphicsPath gp = new System.Drawing.Drawing2D.GraphicsPath())
            {
                g.FillEllipse(brush, centerX - radius, centerY - radius,
                          radius + radius, radius + radius);
            }
        }

        #endregion
    }
}

将其另存为 CircularProgressBar.cs。然后重建解决方案。然后从工具箱将其拖到您的表单中。和表单设置如下...使用

System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using Timer = System.Windows.Forms.Timer;

namespace your namespace
{
    public partial class Form44 : Form
    {
        private int progressValue = 0;

        public Form44()
        {
            InitializeComponent();
        }

        private void Form44_Load(object sender, EventArgs e)
        {
            // Start a new thread to update the progress bar
            Thread progressThread = new Thread(new ThreadStart(UpdateProgressBar));
            progressThread.Start();


        }

        private void UpdateProgressBar()
        {
            while (progressValue <= 100)
            {
                // Update the progress bar value
                this.Invoke((MethodInvoker)delegate
                {
                    circularProgressBar1.Value = progressValue;
                });

                // Simulate a slower progress
                Thread.Sleep(500);

                // Increase the progress value
                progressValue++;
            }
        }


        private void Form44_FormClosing(object sender, FormClosingEventArgs e)
        {
            // Ensure that the thread is terminated when the form is closed
            Environment.Exit(0);
        }




    }
}          

您将获得带有 % 的完美圆形条。您也可以从属性更改圆的宽度

© www.soinside.com 2019 - 2024. All rights reserved.