using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using System.ComponentModel;
using System.Drawing.Drawing2D;
namespace TradeIdeas.TIProGUI
{
public class ProgressBar : System.Windows.Forms.UserControl
{
/*This user control furnishes a horizontal cylidrical progress bar
User is able to use up to colors, with the second color moving
from the bar's right-side towards the left. in this case, the Filler
color will be the middle segment and represents the uncompleted
percentage of a program's progress*/
private double _minValue = 0.0;
private double _value = 0.0;
private double _maxValue = 100.0;
private double _reverseValue = 0.0;
private Color _backgroundColor = Color.FromArgb(255, 255, 255);
private Color _primaryColor = Color.FromArgb(0, 255, 0);
private Color _secondaryColor = Color.FromArgb(255, 0, 0);
private Color _fillerColor = Color.FromArgb(0, 0, 0); //"middle" segment
/*Required:*/
private System.ComponentModel.Container _components = null;
//initialize control...
public ProgressBar()
{
InitializeComponent();
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.DoubleBuffer, true);
this.SetStyle(ControlStyles.ResizeRedraw, true);
this.SetStyle(ControlStyles.Selectable, true);
this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
this.SetStyle(ControlStyles.UserPaint, true);
this.BackColor = Color.Transparent;
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (_components != null)
{
_components.Dispose();
}
}
base.Dispose(disposing);
}
//For Designer support...
private void InitializeComponent()
{
//
// ProgressBar
//
this.Name = "ProgressBar";
this.Size = new System.Drawing.Size(264, 32);
this.Paint += new PaintEventHandler(ProgressBar_Paint);
}
// The below would show in the VS properties tab for this
// control.
[Category("Value"),
DefaultValue(0),
Description("Current value for the ProgressBar.")]
public double Value
{
get
{
return _value;
}
set
{
if (value > MaxValue || value < MinValue)
{
return;
}
_value = value;
ValueChangedHandler vc = ValueChanged;
if (vc != null)
{
vc(this, new System.EventArgs());
}
this.Invalidate();
}
}
[Category("Value"),
DefaultValue(0),
Description("Value property for a right-to-left ProgressBar")]
public double ReverseValue
{
/*The value used for the strip moving from right-to-left*/
get
{
return _reverseValue;
}
set
{
if (value > MaxValue || value < MinValue)
{
return;
}
else
{
_reverseValue = value;
}
ReverseValueHandler rvc = ReverseValueChanged;
if (rvc != null)
{
rvc(this, new System.EventArgs());
}
this.Invalidate();
}
}
///
/// The maximum value for the Value property.
///
[Category("Value"),
DefaultValue(100),
Description("The maximum value for the Value property.")]
public double MaxValue
{
get
{
return _maxValue;
}
set
{
_maxValue = value;
if (value > MaxValue)
{
Value = MaxValue;
}
MaxChangedHandler mc = MaxChanged;
if (mc != null)
{
mc(this, new System.EventArgs());
}
this.Invalidate();
}
}
// The minimum value for the Value property.
[Category("Value"),
DefaultValue(0),
Description("The minimum value for the Value property.")]
public double MinValue
{
get
{
return _minValue;
}
set
{
_minValue = value;
if (value < MinValue)
{
Value = MinValue;
}
MinChangedHandler mc = MinChanged;
if (mc != null)
{
mc(this, new System.EventArgs());
}
this.Invalidate();
}
}
/*Select Color for the strip that moves in the
normal left-to right direction*/
[Category("Bar"),
DefaultValue(typeof(Color), "0, 255, 0"),
Description("Primary color of ProgressBar\n" +
" Moves left to right." )]
public Color MajorColor
{
get
{
return _primaryColor;
}
set
{
_primaryColor = value;
this.Invalidate();
}
}
/*This is the optional secondary color selection-used
if one wishes to have a strip moving from right to left
across the cylinder*/
[Category("Bar"),
DefaultValue(typeof(Color), "255, 0, 0"),
Description("Optional secondary color for ProgressBar." +
" Moves right to left.")]
public Color SecondColor
{
get
{
return _secondaryColor;
}
set
{
_secondaryColor = value;
this.Invalidate();
}
}
public Color BackgroundColor
{
get
{
return _backgroundColor;
}
set
{
_backgroundColor = value;
this.Invalidate();
}
}
[Category("Bar"),
DefaultValue(typeof(Color), "0, 0, 0"),
Description("Middle-segment color for ProgressBar.")]
public Color FillerColor
{
get
{
return _fillerColor;
}
set
{
_fillerColor = value;
this.Invalidate();
}
}
private void DrawBackground(Graphics g)
{
/*This method fills in the background color for our cylinder
*/
Rectangle r = this.ClientRectangle;
GraphicsPath path = new GraphicsPath();
path.AddRectangle(r);
SolidBrush brush = new SolidBrush(this.BackgroundColor);
g.FillPath(brush, path);
path.Dispose();
brush.Dispose();
}
private void DrawBackgroundShadows(Graphics g)
{
/*Here, we add the proper shading to the progress bar's Client Rectangle
in order to give the appearance of a cylinder.*/
Rectangle rect = this.ClientRectangle;
LinearGradientBrush brush = new LinearGradientBrush(rect, Color.Transparent, Color.Transparent, LinearGradientMode.Vertical);
ColorBlend colorBlend = new ColorBlend(5);
int alpha = 145;
colorBlend.Colors[0] = Color.FromArgb(0, 255, 255, 255);
colorBlend.Positions[0] = 0.0f;
colorBlend.Colors[1] = Color.FromArgb(alpha, 255, 255, 255);
colorBlend.Positions[1] = 0.25f;
colorBlend.Colors[2] = colorBlend.Colors[0];
colorBlend.Positions[2] = 0.5f;
colorBlend.Colors[3] = Color.FromArgb(0, 0, 0, 0);
colorBlend.Positions[3] = 0.50001f;
colorBlend.Colors[4] = Color.FromArgb(alpha, 0, 0, 0);
colorBlend.Positions[4] = 1.0f;
brush.InterpolationColors = colorBlend;
g.FillRectangle(brush, rect);
brush.Dispose();
}
private void DrawBar(Graphics g)
{
/*This method does the drawing of the "progress" portion...*/
Rectangle forwardRect = new Rectangle(0, 0, this.Width, this.Height); //forward moving
Rectangle reverseRect = new Rectangle(this.Width, 0, this.Width, this.Height);
Rectangle fillerRect = new Rectangle(0, 0, this.Width, this.Height);//
forwardRect.Width = (int)Math.Round((Value - MinValue) / (MaxValue - MinValue) * this.Width);
fillerRect.Width = (int)Math.Round((MaxValue - MinValue - Value - ReverseValue) / (MaxValue - MinValue) * this.Width);
reverseRect.Width = this.Width - fillerRect.Width - forwardRect.Width;
/*Since the flow of a normal progress bar is left to right, the secondary
bar must remain within the confines of the control. So to give the illusion
of moving from right to left, the location of each new rectangle is pushed
" back" (towards the left) along the cylinder.*/
reverseRect.X = this.Width - reverseRect.Width;
fillerRect.X = forwardRect.Width;
SolidBrush brushMajor = new SolidBrush(_primaryColor);
SolidBrush brushSecondary = new SolidBrush(_secondaryColor);
SolidBrush brushFiller = new SolidBrush(_fillerColor);
g.FillRectangle(brushMajor, forwardRect);
g.FillRectangle(brushSecondary, reverseRect);
g.FillRectangle(brushFiller, fillerRect);
brushMajor.Dispose();
brushSecondary.Dispose();
brushFiller.Dispose();
}
private void ProgressBar_Paint(object sender, PaintEventArgs e)
{
e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
//DrawBackground(e.Graphics);
DrawBar(e.Graphics);
DrawBackgroundShadows(e.Graphics);
}
///
/// When the Value property is changed.
///
public delegate void ValueChangedHandler(object sender,EventArgs e );
///
/// When the Value property is changed.
///
public event ValueChangedHandler ValueChanged;
public void RaiseValueChanged()
{
if (ValueChanged != null)
{
ValueChanged(this, EventArgs.Empty);
}
}
///
/// When the MinValue property is changed.
///
public delegate void MinChangedHandler(object sender, EventArgs e);
///
/// When the MinValue property is changed.
///
public event MinChangedHandler MinChanged;
public void RaiseMinChangeHandler()
{
if (MinChanged != null)
{
MinChanged(this, EventArgs.Empty);
}
}
///
/// When the MaxValue property is changed.
///
public delegate void MaxChangedHandler(object sender, EventArgs e);
///
/// When the MaxValue property is changed.
///
public event MaxChangedHandler MaxChanged;
public void RaiseMaxChangedHandler()
{
if (MaxChanged != null)
{
MaxChanged(this, EventArgs.Empty);
}
}
///
/// When the ReverseValue property is changed.
///
public delegate void ReverseValueHandler(object sender, EventArgs e );
public event ReverseValueHandler ReverseValueChanged;
public void RaiseReverseValueChanged()
{
if (ReverseValueChanged != null)
{
ReverseValueChanged(this, EventArgs.Empty);
}
}
}
}