效果图:
上代码:
其中按标准用户控件创建即可,设计页面无改动;
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();
}
}
}
}