原文的地址:https://www.codeproject.com/Articles/648664/Win-ProgressRing-Control
最终的效果:
自己画的原理图:
下面需要用到的字段名称
const double Indicators_Offet = 11.25; //每个指示器中间的间隔
const int Control_Height = 100; //默认的控件高度
const int Control_Offset = 20;
const int Indicator_Size = 6; //制丝器的数量
const double Start_At = 120.0; //开始的角度
//三角函数数组
double[] sine = new double[1440];
double[] cosine = new double[1440];
Indicator[] indicators = new Indicator[Indicator_Size]
System.Timers.Timer time = null;
int indicator_diameter = 0; //指示器的直径
int indicator_radius = 0; //指示器的半径
int outer_radius = 0; //外半径
int inner_radius = 0; //内半径
int indicator_center_radius = 0; //两个圆心的距离
方法:
public Win10Process()
{
InitializeComponent();
initialize_trigonometry_tables();
adjust_control_dimensions_from_height(Control_Height);
initialize_indicators();
time = new System.Timers.Timer();
this.time.Elapsed += new ElapsedEventHandler(tick);
time.Interval = 100.0;
time.Enabled = true;
}
private void Win10Process_Paint(object sender, PaintEventArgs e)
{
Graphics graphics = e.Graphics;
draw_background_graphic( graphics);
}
方法2:
void initialize_trigonometry_tables()
{
for (int i = 0; i < sine.Length; i++)
{
double degree = i * 0.25;
double radian = CovertRadian(degree);
cosine[i] = Math.Cos(radian);
sine[i] = Math.Sin(radian);
}
}
void adjust_control_dimensions_from_height(int height)
{
indicator_radius = height / Control_Offset;//半径
indicator_diameter = indicator_radius * 2; //直径
int control_height = indicator_radius * Control_Offset; //经过修改过之后的高度
int control_width = control_height; //经过修改之后的宽度
outer_radius = control_height / 2;
inner_radius = outer_radius - indicator_diameter;
indicator_center_radius = outer_radius - indicator_radius;
this.Height = control_height;
this.Width = control_width;
}
//初始化指示器
void initialize_indicators()
{
double degree = Start_At;
for (int i = 0; i < Indicator_Size; i++)
{
indicators[i] = new Indicator(degree);
if (degree < 0)
{
degree += 360;
}
degree -= Indicators_Offet;
}
}
void draw_background_graphic(Graphics graphics)
{
Rectangle rect = new Rectangle();
Brush brush = new SolidBrush(Color.Red);
for (int i = 0; i < Indicator_Size; i++)
{
double degree = indicators[i].Degree;
if (degree < 0)
{
}
int dx = indicator_center_radius + round(indicator_center_radius * cos(degree));
int dy = indicator_center_radius - round(indicator_center_radius * sin(degree));
rect.Size = new Size(indicator_diameter, indicator_diameter);
rect.Location = new Point(dx, dy);
// graphics.DrawLine(Pens.Red, 0,100,dx,dy);
graphics.FillEllipse(brush, rect);
degree -= Indicators_Offet * indicators[i].Fast;
if (indicators[i].Fast > 1.0)
{
indicators[i].Fast += 0.25;
}
if (degree < 0.0)
{
degree += 360;
indicators[i].Fast = 1.25;
}
else if (degree < Start_At)
{
indicators[i].Fast = 1.0;
}
indicators[i].Degree = degree;
}
brush.Dispose();
}
小函数:
int round( double value)
{
return (int)(value + 0.5);
}
double cos(double degree)
{
int index = round(degree / 0.25);
return cosine[index];
}
double sin(double degree)
{
int index = round(degree / 0.25);
return sine[index];
}
//转化为弧
double CovertRadian( double degree)
{
return Math.PI * degree / 180;
}
源代码下载的地址:
https://download.youkuaiyun.com/download/wangtiewei/10375895
备注:
double INDICATOR_OFFSET = 11.25
圆可以分为4个象限,每个象限可以分为8个指示器, 90/8 = 11.25。 为什么是除以8而不是除以6呢? 代码画出来的效果是6个指示器。因为如果是除以6的话,圆点之间的距离就会按着比较近。