Circular Progressbar using C#

Buena tarde amigos, aquí publicando la forma de como crear un barra de progreso de forma circular.

la idea fue tomada del siguiente video en youtube:





Estuve revisando y encontré varios detalles uno de los mas importantes el dimensionar el control el circulo se deformaba, ya que al girarlo a -90 grados el ancho lo tomaba el alto y el alto tomaba el ancho.

por lo que para no tener detalles de una vez se giro y se invirtieron los valores anteriores para que cuando este se re dimensiona tome los valores correctos.

Pero ademas se ideo a forma de que tomara el valor mas que pequeño para que si el ancho es mas pequeño este valor se tome también en la altura y viceversa, y así tener un circulo central.

entonces tomando en cuenta lo anterior si el ancho es mas largo:


y si el alto es mas largo:



También tenemos un proporcional en el tamaño del texto, por lo que:





Ahora tenemos el código completo:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace Joshyba.Controles
{
    [ToolboxBitmap(typeof(ProgressBar))]
    public partial class BarraProgresoCircular : UserControl
    {
        int vValorProgreso;
        int vAncho = 0;
        int vAlto = 0;
        Color Progreso=Color.DarkRed;
        Color FondoProgreso = Color.LightCoral;
        Color FondoCentral = Color.Linen;
        Color Texto = Color.DarkRed;

        public BarraProgresoCircular()
        {
            InitializeComponent();
            vValorProgreso = 10;
            vAncho = this.Width;
            vAlto = this.Height;
            this.SetStyle(ControlStyles.UserPaint | ControlStyles.ResizeRedraw | ControlStyles.SupportsTransparentBackColor | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);
            this.SetStyle(ControlStyles.Opaque, false);
        }


        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            try
            {
                //verificamos cual es el punto mas pequeño
                if (vAlto < vAncho)
                {
                    this.vAncho = vAlto;
                }
                else
                {
                    this.vAlto = vAncho;
                }
                e.Graphics.TranslateTransform(this.Width / 2, this.Height / 2);


                //fondo del circulo===============================================================
                e.Graphics.RotateTransform(-90);
                e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                Pen obj_penx = new Pen(FondoProgreso);
                Rectangle rectx = new Rectangle(0 - this.vAlto / 2 + 12, 0 - this.vAncho / 2 + 12, this.vAlto - 28, this.vAncho - 28);
                //e.Graphics.DrawPie(obj_penx, rectx, 0, 360);
                e.Graphics.FillPie(new SolidBrush(FondoProgreso), rectx, 0, 360);



                e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                Pen obj_pen = new Pen(Progreso);
                Rectangle rect1 = new Rectangle(0 - this.vAlto / 2 + 12, 0 - this.vAncho / 2 + 12, this.vAlto - 28, this.vAncho - 28);
                e.Graphics.DrawPie(obj_pen, rect1, 0, (int)(this.vValorProgreso * 3.6));
                e.Graphics.FillPie(new SolidBrush(Progreso), rect1, 0, (int)(this.vValorProgreso * 3.6));


                //el que tapa el circulo============================================
                e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                Pen obj_pen2 = new Pen(FondoCentral);
                Rectangle rect2 = new Rectangle(0 - this.vAlto / 2 + 32, 0 - this.vAncho / 2 + 32, this.vAlto - 65, this.vAncho - 65);
                e.Graphics.DrawPie(obj_pen2, rect2, 0, 360);
                e.Graphics.FillPie(new SolidBrush(FondoCentral), rect2, 0, 360);

                e.Graphics.RotateTransform(90);
                StringFormat ft = new StringFormat();
                ft.LineAlignment = StringAlignment.Center;
                ft.Alignment = StringAlignment.Center;
                e.Graphics.DrawString(vValorProgreso.ToString() + " %", new Font("Arial", (int)(this.vAncho * 0.135)), new SolidBrush(Texto), rect1, ft);
            }
            catch (Exception)
            {


            }

           
        }

        #region "Propiedades"
        [Category("CustomProperties"), Description("Valor de la barra de progreso")]
        public int Value
        {
            get
            {
                return this.vValorProgreso;
            }
            set
            {
                Application.DoEvents();
                this.vValorProgreso = value;
                this.Refresh();
            }
        }
        [Category("CustomProperties"), Description("Color del progreso")]
        public Color ColorProgreso
        {
            get
            {
                return this.Progreso;
            }
            set
            {
                this.Progreso = value;
            }
        }
        [Category("CustomProperties"), Description("Color del fondo del progreso")]
        public Color ColorFondoProgreso
        {
            get
            {
                return this.FondoProgreso;
            }
            set
            {
                this.FondoProgreso = value;
            }
        }

        [Category("CustomProperties"), Description("Color del fondo del centro del progreso")]
        public Color ColorFondoCentral
        {
            get
            {
                return this.FondoCentral;
            }
            set
            {
                this.FondoCentral = value;
            }
        }

        [Category("CustomProperties"), Description("Color del texto")]
        public Color ColorTexto
        {
            get
            {
                return this.Texto;
            }
            set
            {
                this.Texto = value;
            }
        }

        #endregion

        protected override void OnResize( EventArgs e)
        {
            vAncho = this.Width;
            vAlto = this.Height;
            if(this.ActiveControl !=null)
            {
                this.Refresh();
            }
            base.OnResize(e);
        }

        //Aun no se usa
        private void UpdatePos()
        {
            if (base.IsHandleCreated)
            {
                base.Refresh();
            }
        }
    }
}





Se le añadió la propiedad Value para poder utilizarla:




y listo amigos. cualquier duda, por aquí estamos.

Actualización:

He aquí el code para que lo puedan verificar: Clic aquí para descargar


Comentarios

Publicar un comentario

Entradas populares de este blog

Juego del ahorcado en C# (C Sharp)

RompeCabezas - Juego 1 - VC# 2012

Escribiendo en los TextField de un Pdf con Visual Basic y iTextSharp