[C#]自定义绘制和鼠标捕获拖动的进度条控件

效果图:
效果图
上代码:
其中按标准用户控件创建即可,设计页面无改动;

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ClientSimulation.Controls.DataGenerateControl
{
    [DefaultEvent("ValueChanged")]
    public partial class NameValueTrackBar : UserControl
    {
        public NameValueTrackBar()
        {
            InitializeComponent();
            this.SetStyle(ControlStyles.SupportsTransparentBackColor|
                 ControlStyles.OptimizedDoubleBuffer |
                 ControlStyles.ResizeRedraw, true);
            
        }
        public event EventHandler ValueChanged;
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x00000020; //WS_EX_TRANSPARENT 
                return cp;
            }
        }
        string _trackbarname = "未命名";
        public string TrackBarName
        {
            get
            {
                return _trackbarname;
            }
            set
            {
                _trackbarname = value;
                this.Invalidate();
            }
        }
        bool _isHorizontal = true;
        public bool IsHorizontal
        {
            get
            {
                return _isHorizontal;
            }
            set
            {
                _isHorizontal = value;
                this.Invalidate();
            }
        }
        public int BarWidth
        {
            get;
            set;
        } = 5;
        int _maxvalue = 100;
        public int MaxValue
        {
            get
            {
                return _maxvalue;
            }
            set
            {
                if (value > MinValue)
                {
                    _maxvalue = value;
                    if (Value > _maxvalue)
                    {
                        Value = _maxvalue;
                    }
                }
            }
        }
        int _minvalue = 0;
        public int MinValue
        {
            get
            {
                return _minvalue;
            }
            set
            {
                if (value < MaxValue)
                {
                    _minvalue = value;
                    if (Value < _minvalue)
                    {
                        Value = _minvalue;
                    }
                }
            }
        } 
        int _value = 50;
        public int Value
        {
            get
            {
                return _value;
            }
            set
            {
                if (value < MinValue)
                {
                    value = MinValue;
                }
                if (value > MaxValue)
                {
                    value = MaxValue;
                }
                if (_value != value)
                {
                    _value = value;
                    this.Invalidate();
                    ValueChanged?.Invoke(this, new EventArgs());
                }
            }
        }
        public Color BarColor
        {
            get;
            set;
        } = Color.FromArgb(255,80, 80, 80);
        public Color TextColor
        {
            get;
            set;
        } = Color.FromArgb(255, 0, 0, 255);
        public Color NameColor
        {
            get;
            set;
        } = Color.FromArgb(255, 0, 0, 0);
        public int BallWidth
        {
            get;
            set;
        } = 15;
        public Color BallColor
        {
            get;
            set;
        } = Color.FromArgb(255, 0, 180, 180);
        int margin = 10;
        public int BarMargin
        {
            get
            {
                return margin;
            }
            set
            {
                margin = value;
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            Bitmap bitmap = new Bitmap(this.Width, this.Height);
            Graphics gra = Graphics.FromImage(bitmap);
            gra.Clear(this.BackColor);
            int centerY = this.Height / 2;
            int centerX = this.Width / 2;
            //
            Pen pen1 = new Pen(BarColor, BarWidth);
            Brush brush1 = new SolidBrush(BallColor);
            Brush brush2 = new SolidBrush(TextColor);
            Brush brush3 = new SolidBrush(NameColor);
            double rad = BallWidth / 2.0;
            double percengt = (Value - MinValue + 0.0) / (MaxValue - MinValue);
            if (IsHorizontal)
            {//水平方向
                Point p1 = new Point(margin, centerY);
                Point p2 = new Point(this.Width - margin, centerY);
                gra.DrawLine(pen1, p1, p2);
                int currentX = margin + (int)(percengt * (this.Width - margin * 2) - rad);
                int currentY = (int)(centerY - rad);
                gra.FillEllipse(brush1, currentX, currentY, BallWidth, BallWidth);
                gra.DrawString("" + Value, this.Font, brush2, currentX, currentY);
                gra.DrawString(TrackBarName, this.Font, brush3, 0, 0);
            }
            else
            {
                Point p1 = new Point(centerX, margin);
                Point p2 = new Point(centerX, this.Height - margin);
                gra.DrawLine(pen1, p1, p2);
                int currentX = (int)(centerX - rad);
                int currentY = margin + (int)(percengt * (this.Height - margin * 2) - rad);
                gra.FillEllipse(brush1, currentX, currentY, BallWidth, BallWidth);
                gra.DrawString("" + Value, this.Font, brush2, currentX, currentY);
                gra.DrawString(TrackBarName, this.Font, brush3, 0, 0);
            }
            Graphics g = e.Graphics;
            gra.Save();
            g.DrawImage(bitmap, 0, 0);
            g.Save();
            gra.Dispose();
            bitmap.Dispose();
        }

        bool dragFlag = false;
        private void TransparentTrackBar_MouseDown(object sender, MouseEventArgs e)
        {
            bool hitFlag = false;
            int centerY = this.Height / 2;
            int centerX = this.Width / 2;
            int rad = BallWidth / 2;
            double percengt = (Value - MinValue + 0.0) / (MaxValue - MinValue);
            if (IsHorizontal)
            {//水平方向
                int currentX = margin + (int)(percengt * (this.Width - margin*2) - rad);
                int currentY = centerY - rad;
                if (Math.Abs(e.Location.Y - currentY)  <= rad * 3)
                {
                    hitFlag = true;
                }
            }
            else
            {
                int currentX = centerX - rad;
                int currentY = margin + (int)(percengt * (this.Height - margin*2) - rad);
                if (Math.Abs(e.Location.X - currentX)  <= rad * 3)
                {
                    hitFlag = true;
                }
            }
            if (hitFlag)
            {
                dragFlag = true;
                SetValueByMousePoint(e.Location);
            }
        }
        private void SetValueByMousePoint(Point p)
        {
            if (IsHorizontal)
            {//水平方向
                int x0 = margin;
                int x1 = margin + (this.Width - margin * 2);
                double percentage = (p.X - x0) / (x1 - x0 + 0.0);
                if (percentage > 1)
                {
                    percentage = 1;
                }
                if (percentage < 0)
                {
                    percentage = 0;
                }
                Value = (int)(percentage * (MaxValue - MinValue));
            }
            else
            {
                int y0 = margin;
                int y1 = margin + (this.Height - margin * 2);
                double percentage = (p.Y - y0) / (y1 - y0 + 0.0);
                if (percentage > 1)
                {
                    percentage = 1;
                }
                if (percentage < 0)
                {
                    percentage = 0;
                }
                Value = (int)(percentage * (MaxValue - MinValue));
            }
        }
        private void TransparentTrackBar_MouseMove(object sender, MouseEventArgs e)
        {
            if (dragFlag)
            {
                SetValueByMousePoint(e.Location);
            }
        }

        private void TransparentTrackBar_MouseUp(object sender, MouseEventArgs e)
        {
            dragFlag = false;
        }

        private void NameValueTrackBar_Resize(object sender, EventArgs e)
        {
            this.Invalidate();
        }

        Version win7 = new Version(6, 1);
        private void timer1_Tick(object sender, EventArgs e)
        {
            if (System.Environment.OSVersion.Version > win7)
            {//Win10需要定时刷新,不然会有最小化以后不显示的现象
                this.Invalidate();
            }
        }
    }
}

你可能感兴趣的:(C#桌面工具)