- A+
所属分类:.NET技术
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(); } }