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
excelente ejemplo de barra de progreso
ResponderEliminar