public class ZhmSlider : Control { private Rectangle foreRect; private Rectangle backRect; private Rectangle setRect; private Color backgroundColor = ...
public class ZhmSlider : Control
{
private Rectangle foreRect;
private Rectangle backRect;
private Rectangle setRect;
private Color backgroundColor = Color.White;
private Color foregroundColor = Color.Gray;
private Color setRectColor = Color.Black;//滑塊顏色
private Color fontColor = Color.Black;
private Color borderColor = Color.Black;
private int maximum = 100; //進度條最大值
private int minimum = 0; //進度條最小值
private double _value = 0;//進度條當前值
private bool showPercent; //當前進度百分比
private float fontSize = 9;//
private FontFamily _fontFamily = new FontFamily("Segoe UI");
private Point originPoint;
private Point originsetRectPoint;
private bool setRectDown = false;
public ZhmSlider()
{
// 避免重繪時視窗閃爍
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.UserPaint, true);
this.MouseDown += ZhmSlider_MouseDown;
this.MouseMove += ZhmSlider_MouseMove;
this.MouseUp += ZhmSlider_MouseUp;
}
private void ZhmSlider_MouseUp(object sender, MouseEventArgs e)
{
setRectDown = false;
}
private void ZhmSlider_MouseMove(object sender, MouseEventArgs e)
{
if (setRectDown)
{
int dd = e.Location.X - originPoint.X;
double percent = (double)(originsetRectPoint.X + dd - this.backRect.X) / (this.backRect.Width - this.backRect.Height);
if (percent < 0)
{
this.Value = minimum;
this.foreRect.Width = 0;
this.setRect.X = backRect.X;
}
else if (percent > 1)
{
this.Value = maximum;
this.foreRect.Width = this.backRect.Width;
this.setRect.X = backRect.X + backRect.Width - backRect.Height;
}
else
{
this.Value = percent * maximum;
this.foreRect.Width = (int)(percent * this.backRect.Width);
this.setRect.X = originsetRectPoint.X + dd;
}
Invalidate();
}
}
private void ZhmSlider_MouseDown(object sender, MouseEventArgs e)
{
if (setRect.Contains(e.Location))
{
this.originPoint = e.Location;
originsetRectPoint = this.setRect.Location;
this.setRectDown = true;
}
}
[Category("擴展屬性"), Browsable(true)]
public bool ShowPercentTag
{
get { return showPercent; }
set
{
showPercent = value;
Invalidate();
}
}
[Category("擴展屬性"), Browsable(true)]
public int Maximum
{
get { return maximum; }
set
{
maximum = value;
Invalidate();
}
}
[Category("擴展屬性"), Browsable(true)]
public int Minimum
{
get { return minimum; }
set
{
minimum = value;
Invalidate();
}
}
[Category("擴展屬性"), Browsable(true)]
public float FontSize
{
get { return fontSize; }
set
{
this.fontSize = value;
Invalidate();
}
}
[Category("擴展屬性"), Browsable(true)]
public FontFamily FontFamily
{
get { return _fontFamily; }
set
{
this._fontFamily = value;
Invalidate();
}
}
[Category("擴展屬性"), Browsable(true)]
public Color BackgroundColor
{
get { return backgroundColor; }
set
{
this.backgroundColor = value;
Invalidate();
}
}
[Category("擴展屬性"), Browsable(true)]
public Color ForegroundColor
{
get { return foregroundColor; }
set
{
this.foregroundColor = value;
Invalidate();
}
}
[Category("擴展屬性"), Browsable(true)]
public Color SetRectColor
{
get { return setRectColor; }
set
{
this.setRectColor = value;
Invalidate();
}
}
[Category("擴展屬性"), Browsable(true)]
public Color FontColor
{
get { return fontColor; }
set
{
this.fontColor = value;
Invalidate();
}
}
[Category("擴展屬性"), Browsable(true)]
public Color BorderColor
{
get { return borderColor; }
set
{
this.borderColor = value;
Invalidate();
}
}
//確定控制項的位置。 我們根據寬度和高度屬性確定矩形的位置。 因為Control類也有這兩個屬性,所以我們在前面添加new來覆蓋原來的屬性
[Category("擴展屬性"), Browsable(true)]
public new int Width
{
get { return base.Width; }
set
{
base.Width = value;
foreRect.X = backRect.X = base.Width / 20;
backRect.Width = base.Width * 9 / 10;
foreRect.Width = (int)(_value / maximum * backRect.Width);
setRect.X = (int)(_value / maximum * (backRect.Width - backRect.Height) + foreRect.X);
Invalidate();
}
}
[Category("擴展屬性"), Browsable(true)]
public new int Height
{
get { return base.Height; }
set
{
base.Height = value;
foreRect.Height = backRect.Height = setRect.Height = setRect.Width = base.Height / 3;
foreRect.Y = backRect.Y = setRect.Y = base.Height / 3;
Invalidate();
}
}
//值發生變化的屬性。 當向事件添加外部響應函數時,事件將生效,否則OnValueChanged方法的值為空
protected EventHandler OnValueChanged;
public event EventHandler ValueChanged
{
add
{
if (OnValueChanged != null)
foreach (Delegate d in OnValueChanged.GetInvocationList())
if (object.ReferenceEquals(d, value)) return;
OnValueChanged = (EventHandler)Delegate.Combine(OnValueChanged, value);
}
remove
{
OnValueChanged = (EventHandler)Delegate.Remove(OnValueChanged, value);
}
}
//定義value的值。 當Value值發生變化時,重置矩形的進度,控制塊的位置,並重新繪製控制項(如果在value屬性中修改進度條的值,請使用_value變數,在其他地方,請使Value屬性 )
[Category("擴展屬性"), Browsable(true)]
public double Value
{
get { return _value; }
set
{
if (_value < Minimum)
throw new ArgumentException("Less than minimum");
if (_value > Maximum)
throw new ArgumentException("Exceeds the maximum");
_value = value;
foreRect.Width = (int)(_value / maximum * backRect.Width);
setRect.X = (int)(_value / maximum * (backRect.Width - backRect.Height) + backRect.X);
if ((_value - maximum) > 0)
{
foreRect.Width = backRect.Width;
setRect.X = backRect.Width - backRect.Height + backRect.X;
}
if (OnValueChanged != null)
OnValueChanged(this, EventArgs.Empty);
Invalidate();
}
}
//繪製控制項,重載OnPaint方法來繪製控制項
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
DrawRect(pe.Graphics);
DrawText(pe.Graphics);
}
//滑塊區域
private void DrawRect(Graphics e)
{
Pen pen = new Pen(this.foregroundColor);
e.FillRectangle(new SolidBrush(this.backgroundColor), backRect);
e.DrawRectangle(new Pen(this.borderColor), backRect);
e.FillRectangle(new SolidBrush(this.foregroundColor), foreRect);
e.DrawRectangle(new Pen(this.borderColor), foreRect);
e.FillRectangle(new SolidBrush(this.setRectColor), setRect);
e.DrawRectangle(new Pen(this.borderColor), setRect);
}
// 繪製文本
private void DrawText(Graphics e)
{
Point point = new Point();
point.X = this.backRect.X + this.backRect.Width * 3 / 7;
point.Y = this.backRect.Y + this.backRect.Height / 3;
SolidBrush brush = new SolidBrush(fontColor);
Font font = new Font(_fontFamily, this.fontSize);
string percent = ((int)this._value).ToString() + "%";
//設置文本居中
StringFormat format = new StringFormat();
format.Alignment = StringAlignment.Center;
format.LineAlignment = StringAlignment.Center;
e.DrawString(percent, font, brush, backRect, format);
}
//在設計期間更改控制項的大小時調用OnResize方法。 當您拖動邊緣上的箭頭來更改控制項的大小時,當需要對控制項進行相應更改時,可以重寫此方法。如果沒有重新載入,則只有在修改完成後才會更新控制項。
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
this.Width = Width;
this.Height = Height;
Invalidate();
}
}