/// <summary>
/// 水波纹进度控件
/// </summary>
[ToolboxItem(true)]
[DefaultProperty("Value")]
[DefaultEvent("ValueChanged")]
[Description("水波纹进度控件")]
public partial class WaveProgressExt : Control
{
public delegate void ValueEventHandler(object sender, ValueEventArgs e);
#region
private event ValueEventHandler valueChanged;
/// <summary>
/// 进度值更改事件
/// </summary>
[Description("进度值更改事件")]
public event ValueEventHandler ValueChanged
{
add { this.valueChanged += value; }
remove { this.valueChanged -= value; }
}
private WaveProgressType type = WaveProgressType.Circle;
/// <summary>
/// 外观类型
/// </summary>
[DefaultValue(WaveProgressType.Circle)]
[Description("外观类型")]
public WaveProgressType Type
{
get { return this.type; }
set
{
if (this.type == value)
return;
this.type = value;
this.Invalidate();
}
}
private bool active = false;
/// <summary>
/// 动画状态
/// </summary>
[DefaultValue(false)]
[Description("动画状态")]
public bool Active
{
get { return this.active; }
set
{
if (this.active == value)
return;
this.active = value;
this.waveTimer.Enabled = value;
}
}
private bool borderShow = true;
/// <summary>
/// 是否显示边框
/// </summary>
[DefaultValue(true)]
[Description("是否显示边框")]
public bool BorderShow
{
get { return this.borderShow; }
set
{
if (this.borderShow == value)
return;
this.borderShow = value;
this.Invalidate();
}
}
#region 水波纹
private int waveInterval = 5;
/// <summary>
/// 水波纹移动速度
/// </summary>
[DefaultValue(5)]
[Description("水波纹移动速度")]
public int WaveInterval
{
get { return this.waveInterval; }
set
{
if (this.waveInterval == value || value < 0)
return;
this.waveInterval = value;
}
}
private float waveTension = 0.5f;
/// <summary>
/// 水波纹曲线的张力(0-1)
/// </summary>
[DefaultValue(0.5f)]
[Description("水波纹曲线的张力(0-1)")]
public float WaveTension
{
get { return this.waveTension; }
set
{
if (this.waveTension == value || value < 0 || value > 1)
return;
this.waveTension = value;
this.InitializeWave();
this.Invalidate();
}
}
private int waveWidth = 30;
/// <summary>
/// 水波纹宽度
/// </summary>
[DefaultValue(30)]
[Description("水波纹宽度")]
public int WaveWidth
{
get { return this.waveWidth; }
set
{
if (this.waveWidth == value || value < 1)
return;
this.waveWidth = value;
this.InitializeWave();
this.Invalidate();
}
}
private int waveHeight = 10;
/// <summary>
/// 水波纹高度
/// </summary>
[DefaultValue(10)]
[Description("水波纹高度")]
public int WaveHeight
{
get { return this.waveHeight; }
set
{
if (this.waveHeight == value || value < 1)
return;
this.waveHeight = value;
this.InitializeWave();
this.Invalidate();
}
}
private Color waveBackColor = Color.Empty;
/// <summary>
/// 水波纹背景颜色
/// </summary>
[DefaultValue(typeof(Color), "Empty")]
[Description("水波纹背景颜色")]
[Editor(typeof(ColorEditorExt), typeof(System.Drawing.Design.UITypeEditor))]
public Color WaveBackColor
{
get { return this.waveBackColor; }
set
{
if (this.waveBackColor == value)
return;
this.waveBackColor = value;
this.Invalidate();
}
}
private Color waveFrontColor = Color.FromArgb(104, 135, 206, 250);
/// <summary>
/// 水波纹前方颜色
/// </summary>
[DefaultValue(typeof(Color), "104, 135, 206, 250")]
[Description("水波纹前方颜色")]
[Editor(typeof(ColorEditorExt), typeof(System.Drawing.Design.UITypeEditor))]
public Color WaveFrontColor
{
get { return this.waveFrontColor; }
set
{
if (this.waveFrontColor == value)
return;
this.waveFrontColor = value;
this.Invalidate();
}
}
private Color waveBehindColor = Color.FromArgb(104, 135, 206, 250);
/// <summary>
/// 水波纹后方颜色
/// </summary>
[DefaultValue(typeof(Color), "104, 135, 206, 250")]
[Description("水波纹后方颜色")]
[Editor(typeof(ColorEditorExt), typeof(System.Drawing.Design.UITypeEditor))]
public Color WaveBehindColor
{
get { return this.waveBehindColor; }
set
{
if (this.waveBehindColor == value)
return;
this.waveBehindColor = value;
this.Invalidate();
}
}
#endregion
#region 进度值
private bool valueShow = true;
/// <summary>
/// 是否显示进度值
/// </summary>
[DefaultValue(true)]
[Description("是否显示进度值")]
public bool ValueShow
{
get { return this.valueShow; }
set
{
if (this.valueShow == value)
return;
this.valueShow = value;
this.Invalidate();
}
}
private float value = 0.0f;
/// <summary>
/// 进度值(0-1)
/// </summary>
[DefaultValue(0.0f)]
[Description("进度值")]
public float Value
{
get { return this.value; }
set
{
if (this.value == value)
return;
if (value > 1)
value = 1;
if (value < 0)
value = 0;
this.value = value;
this.Invalidate();
if (this.valueChanged != null)
{
this.valueChanged(this, new ValueEventArgs() { Value = value });
}
}
}
private Font valueFont = new Font("宋体", 13, FontStyle.Bold);
/// <summary>
/// 进度值字体
/// </summary>
[DefaultValue(typeof(Font), "13pt style=Bold")]
[Description("进度值字体")]
public Font ValueFont
{
get { return this.valueFont; }
set
{
if (this.valueFont == value)
return;
this.valueFont = value;
this.Invalidate();
}
}
private Color valueColor = Color.FromArgb(183, 240, 128, 128);
/// <summary>
/// 进度值颜色
/// </summary>
[DefaultValue(typeof(Color), "183, 240, 128, 128")]
[Description("进度值颜色")]
[Editor(typeof(ColorEditorExt), typeof(System.Drawing.Design.UITypeEditor))]
public Color ValueColor
{
get { return this.valueColor; }
set
{
if (this.valueColor == value)
return;
this.valueColor = value;
this.Invalidate();
}
}
#endregion
[Editor(typeof(ColorEditorExt), typeof(System.Drawing.Design.UITypeEditor))]
public override Color BackColor
{
get
{
return base.BackColor;
}
set
{
base.BackColor = value;
}
}
protected override Size DefaultSize
{
get
{
return new Size(100, 100); ;
}
}
/// <summary>
/// 水波纹移动定时器
/// </summary>
private Timer waveTimer;
/// <summary>
/// 水波纹移动距离
/// </summary>
int wave_distance = 0;
/// <summary>
/// 前面水波纹坐标
/// </summary>
List<Point> waveFrontPointList = new List<Point>();
/// <summary>
/// 后面水波纹坐标
/// </summary>
List<Point> waveBehindPointList = new List<Point>();
#endregion
public WaveProgressExt()
{
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
InitializeComponent();
this.InitializeWave();
this.waveTimer = new Timer();
this.waveTimer.Interval = 100;
this.waveTimer.Tick += new EventHandler(this.time_Tick);
}
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
base.OnPaint(e);
Graphics g = e.Graphics;
Rectangle rect = e.ClipRectangle;
g.SmoothingMode = SmoothingMode.AntiAlias;
if (this.Type == WaveProgressType.Circle)
{
GraphicsPath gp = new GraphicsPath();
gp.AddEllipse(rect);
g.SetClip(gp);
gp.Dispose();
}
#region 水波纹背景
if (this.WaveBackColor != Color.Empty)
{
SolidBrush waveback_sb = new SolidBrush(this.WaveBackColor);
if (this.Type == WaveProgressType.Circle)
g.FillEllipse(waveback_sb, new Rectangle(rect.X + 2, rect.Y + 2, rect.Width - 4, rect.Height - 4));
else
g.FillRectangle(waveback_sb, new Rectangle(rect.X, rect.Y, rect.Width - 2, rect.Height - 2));
waveback_sb.Dispose();
}
#endregion
#region 水波纹
if (this.waveFrontPointList.Count > 0)
{
SolidBrush behind_sb = new SolidBrush(this.WaveBehindColor);
SolidBrush front_sb = new SolidBrush(this.WaveFrontColor);
Point[] behindPoint = new Point[this.waveFrontPointList.Count + 2];
Point[] frontPoint = new Point[this.waveFrontPointList.Count + 2];
int value_h = (int)(this.Value * rect.Height);
for (int i = 0; i < this.waveFrontPointList.Count; i++)
{
behindPoint[i] = new Point(this.waveBehindPointList[i].X - this.wave_distance, rect.Bottom - this.waveBehindPointList[i].Y - value_h + this.WaveHeight / 3);
frontPoint[i] = new Point(this.waveFrontPointList[i].X + this.wave_distance, rect.Bottom - this.waveFrontPointList[i].Y - value_h);
}
behindPoint[this.waveFrontPointList.Count] = new Point(behindPoint[this.waveFrontPointList.Count - 1].X, rect.Bottom);
behindPoint[this.waveFrontPointList.Count + 1] = new Point(behindPoint[0].X, rect.Bottom);
frontPoint[this.waveFrontPointList.Count] = new Point(frontPoint[this.waveFrontPointList.Count - 1].X, rect.Bottom);
frontPoint[this.waveFrontPointList.Count + 1] = new Point(frontPoint[0].X, rect.Bottom);
g.FillClosedCurve(behind_sb, behindPoint, FillMode.Alternate, this.WaveTension);
g.FillClosedCurve(front_sb, frontPoint, FillMode.Alternate, this.WaveTension);
front_sb.Dispose();
behind_sb.Dispose();
#region 进度值
if (this.ValueShow)
{
g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
string value_str = (this.Value * 100).ToString("F0").PadLeft(3, ' ') + "%";
Size value_size = TextRenderer.MeasureText(value_str, this.ValueFont, new Size(), TextFormatFlags.NoPadding);
Rectangle value_rect = new Rectangle((rect.Width - value_size.Width) / 2, (rect.Height - value_size.Height) / 2, value_size.Width, value_size.Height);
TextRenderer.DrawText(g, value_str, this.ValueFont, value_rect, this.ValueColor, TextFormatFlags.NoPadding);
}
#endregion
#region 边框
if (this.Type == WaveProgressType.Circle)
{
//利用背景色消除锯齿
Pen back_pen = new Pen(this.BackColor);
g.DrawEllipse(back_pen, rect);
back_pen.Dispose();
if (this.BorderShow)
{
Pen border_pen = new Pen(this.WaveFrontColor, 2);
g.DrawEllipse(border_pen, new Rectangle(rect.X + 2, rect.Y + 2, rect.Width - 4, rect.Height - 4));
border_pen.Dispose();
}
}
else
{
if (this.BorderShow)
{
Pen border_pen = new Pen(this.WaveFrontColor, 2);
g.DrawRectangle(border_pen, new Rectangle(rect.X, rect.Y, rect.Width - 2, rect.Height - 2));
border_pen.Dispose();
}
}
#endregion
}
#endregion
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
this.InitializeWave();
}
/// <summary>
/// 水波纹移动动画
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void time_Tick(object sender, EventArgs e)
{
this.wave_distance += this.WaveInterval;
if (this.wave_distance >= this.WaveWidth * 2)
{
this.wave_distance = 0;
}
this.Invalidate();
}
/// <summary>
/// 初始化波浪纹
/// </summary>
protected void InitializeWave()
{
this.waveFrontPointList.Clear();
this.waveBehindPointList.Clear();
int startFront_x = this.ClientRectangle.X - this.WaveWidth * 4;
int start_y = 0;
int startBehind_x = this.ClientRectangle.Right + this.WaveWidth * 4;
int i = 0;
while (true)
{
startFront_x += this.WaveWidth;
startBehind_x -= this.WaveWidth;
start_y = this.WaveHeight * (i % 2);
this.waveFrontPointList.Add(new Point(startFront_x, start_y));
this.waveBehindPointList.Add(new Point(startBehind_x, start_y));
if (startFront_x >= this.ClientRectangle.Right && start_y == 0)
{
this.wave_distance = 0;
return;
}
i++;
}
}
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
if (this.waveTimer != null)
{
this.waveTimer.Dispose();
}
}
base.Dispose(disposing);
}
/// <summary>
/// 外观类型
/// </summary>
[Description("外观类型")]
public enum WaveProgressType
{
/// <summary>
/// 四边形
/// </summary>
Flat,
/// <summary>
/// 圆形
/// </summary>
Circle
}
/// <summary>
/// 进度值更改事件参数
/// </summary>
[Description("进度值更改事件参数")]
public class ValueEventArgs : EventArgs
{
/// <summary>
/// 进度值
/// </summary>
[Description("进度值")]
public float Value { get; set; }
}
}
源码下载:水波纹进度控件.zip
来源:oschina
链接:https://my.oschina.net/u/4384187/blog/3415611