Skip to content

Instantly share code, notes, and snippets.

@AlexTR-Dev
Last active May 19, 2019 13:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AlexTR-Dev/dd6976300e675efbacc14de7c9f9a55e to your computer and use it in GitHub Desktop.
Save AlexTR-Dev/dd6976300e675efbacc14de7c9f9a55e to your computer and use it in GitHub Desktop.
ProgressBar with Color Gradient,, Text and Thickness options
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace ControlesAlejandro
{
#region enumeration types
public enum ProgressBarGradient
{
Horizontal,
Vertical,
ForwardDiagonal,
BackwardDiagonal
}
public enum ProgressBarMode
{
NoText,
Percentage,
Progress,
CustomText,
TextAndPercentage,
TextAndCurrProgress
}
#endregion
public partial class ProgressBarLinear : ProgressBar
{
private const string CategoryName = "ProgressBar Appearance";
public ProgressBarLinear()
{
InitializeComponent();
FixComponentBlinking();
Style = ProgressBarStyle.Marquee;
}
#region Progress Bar Style
[Category(CategoryName), Browsable(true)]
public ProgressBarMode VisualMode
{
get => _visualMode;
set
{
_visualMode = value;
Invalidate();
}
}
private ProgressBarMode _visualMode = ProgressBarMode.Percentage;
[Category(CategoryName), Browsable(true)]
public ProgressBarGradient GradientMode
{
get => gradientMode;
set
{
gradientMode = value;
Invalidate();
}
}
private ProgressBarGradient gradientMode = ProgressBarGradient.Vertical;
[Description("The Border Color of the gradient in the Progress Bar"), Category(CategoryName), Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
public Color BarColor1
{
get => barColor1;
set
{
barColor1 = value;
Invalidate(); ;
}
}
private Color barColor1 = Color.LightGray;
[Description("The Center Color of the gradient in the Progress Bar"), Category(CategoryName), Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
public Color BarColor2
{
get { return barColor2; }
set
{
barColor2 = value;
Invalidate(); ;
}
}
private Color barColor2 = Color.DarkBlue;
[Category(CategoryName), Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
public override Color BackColor
{
get => backColor;
set
{
if (value != Color.Transparent)
{
backColor = base.BackColor = value;
Invalidate();
}
else
{
MessageBox.Show("El Color seleccionado no es válido", "Ventana de Propiedades", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
}
private Color backColor = Color.White;
private int thickness = 0;
[Description("Separation from the edges"), Category(CategoryName), Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
public int Thickness
{
get => thickness;
set
{
thickness = value;
Invalidate();
}
}
#endregion
#region Text
[Category(CategoryName), Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
public override string Text
{
get => text;
set
{
text = value;
Invalidate();//redraw component after change value from VS Properties section
}
}
private string text = string.Empty;
private string GetTextToDraw()
{
switch (VisualMode)
{
case (ProgressBarMode.Percentage):
return PercentageStr;
case (ProgressBarMode.Progress):
return CurrProgressStr;
case (ProgressBarMode.TextAndCurrProgress):
return $"{text} {CurrProgressStr}";
case (ProgressBarMode.TextAndPercentage):
return $"{text} {PercentageStr}";
case ProgressBarMode.NoText:
break;
case ProgressBarMode.CustomText:
return text;
}
return text;
}
private string PercentageStr => $"{(int)((float)Value - Minimum) / ((float)Maximum - Minimum) * 100 } %";
private string CurrProgressStr => $"{Value}/{Maximum}";
[Category(CategoryName), Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
public override Font Font
{
get => font;
set
{
font.Dispose();
font = base.Font = value;
Invalidate();
}
}
private Font font = new Font(FontFamily.GenericSerif, 11, FontStyle.Bold | FontStyle.Italic);
[Category(CategoryName), Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
public override Color ForeColor
{
get => foreColor;
set
{
foreColor = base.ForeColor = value;
Invalidate();
}
}
private Color foreColor;
#endregion
#region On Paint
private void FixComponentBlinking()
{
SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);
}
protected override void OnPaint(PaintEventArgs e)
{
DrawProgressBar(e.Graphics);
DrawString(e.Graphics);
}
protected override Size DefaultSize
{
get { return new Size(200, 15); }
}
#endregion
#region DrawProgressBar
private void DrawProgressBar(Graphics graphics)
{
Rectangle rect = ClientRectangle;
const int inset = 0;
graphics.SmoothingMode = SmoothingMode.AntiAlias;
using (Bitmap bitmap = new Bitmap(Width, Height))
{
using (Graphics g = Graphics.FromImage(bitmap))
{
if (ProgressBarRenderer.IsSupported)
ProgressBarRenderer.DrawHorizontalBar(g, rect);
g.Clear(backColor);
rect.Inflate(new Size(-inset, -thickness));
rect.Width = Convert.ToInt32(value: Math.Round(rect.Width * (double)Value / Maximum) + 1); // se agrega 1 para compensar que se sesajusta en -1 en la posición de offscree.FillRectangle
if (rect.Width <= 0) rect.Width = 1;
if (rect.Height <= 0) rect.Height = 1;
using (LinearGradientBrush brush = new LinearGradientBrush(rect, barColor1, barColor2, linearGradientMode: (LinearGradientMode)GradientMode))
{
g.FillRectangle(brush, inset - 1, thickness, rect.Width, rect.Height); ///Set desajusta la posición x en -1 para ocultar el recuadro.
graphics.DrawImage(bitmap, 0, 0);
}
}
}
}
private void DrawString(Graphics graphics)
{
if (VisualMode != ProgressBarMode.NoText)
{
string text = GetTextToDraw();
SizeF len = graphics.MeasureString(text, font);
Point location = new Point(Convert.ToInt16((Width - len.Width) / 2), Convert.ToInt16((Height - len.Height) / 2));
using (SolidBrush brush = new SolidBrush(foreColor))
{
graphics.DrawString(text, font, brush, location);
}
}
}
protected new void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment