官网

http://www.hzhcontrols.com

前提

入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。

GitHub:https://github.com/kwwwvagaa/NetWinformControl

码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git

如果觉得写的还行,请点个 star 支持一下吧

欢迎前来交流探讨: 企鹅群568015492 

麻烦博客下方点个【推荐】,谢谢

NuGet

Install-Package HZH_Controls

目录

https://www.cnblogs.com/bfyx/p/11364884.html

用处及效果

准备工作

依然使用GDI+画的,不懂的话就百度一下吧

另外主要用到了三角函数,如果不懂,可以向初中的数学老师再问问(你也可以百度一下)

开始

添加一个类UCMeter 继承 UserControl

首先添加一个需要控制的属性

 private int splitCount = ;
/// <summary>
/// Gets or sets the split count.
/// </summary>
/// <value>The split count.</value>
[Description("分隔刻度数量,>1"), Category("自定义")]
public int SplitCount
{
get { return splitCount; }
set
{
if (value < )
return;
splitCount = value;
Refresh();
}
} private int meterDegrees = ;
/// <summary>
/// Gets or sets the meter degrees.
/// </summary>
/// <value>The meter degrees.</value>
[Description("表盘跨度角度,0-360"), Category("自定义")]
public int MeterDegrees
{
get { return meterDegrees; }
set
{
if (value > || value <= )
return;
meterDegrees = value;
Refresh();
}
} private decimal minValue = ;
/// <summary>
/// Gets or sets the minimum value.
/// </summary>
/// <value>The minimum value.</value>
[Description("最小值,<MaxValue"), Category("自定义")]
public decimal MinValue
{
get { return minValue; }
set
{
if (value >= maxValue)
return;
minValue = value;
Refresh();
}
} private decimal maxValue = ;
/// <summary>
/// Gets or sets the maximum value.
/// </summary>
/// <value>The maximum value.</value>
[Description("最大值,>MinValue"), Category("自定义")]
public decimal MaxValue
{
get { return maxValue; }
set
{
if (value <= minValue)
return;
maxValue = value;
Refresh();
}
}
/// <summary>
/// 获取或设置控件显示的文字的字体。
/// </summary>
/// <value>The font.</value>
/// <PermissionSet>
/// <IPermission class="System.Security.Permissions.EnvironmentPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
/// <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
/// <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="UnmanagedCode, ControlEvidence" />
/// <IPermission class="System.Diagnostics.PerformanceCounterPermission, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
/// </PermissionSet>
[Description("刻度字体"), Category("自定义")]
public override Font Font
{
get
{
return base.Font;
}
set
{
base.Font = value;
Refresh();
}
} private decimal m_value = ;
/// <summary>
/// Gets or sets the value.
/// </summary>
/// <value>The value.</value>
[Description("值,>=MinValue并且<=MaxValue"), Category("自定义")]
public decimal Value
{
get { return m_value; }
set
{
if (value < minValue || value > maxValue)
return;
m_value = value;
Refresh();
}
} private MeterTextLocation textLocation = MeterTextLocation.None;
/// <summary>
/// Gets or sets the text location.
/// </summary>
/// <value>The text location.</value>
[Description("值和固定文字显示位置"), Category("自定义")]
public MeterTextLocation TextLocation
{
get { return textLocation; }
set
{
textLocation = value;
Refresh();
}
} private string fixedText;
/// <summary>
/// Gets or sets the fixed text.
/// </summary>
/// <value>The fixed text.</value>
[Description("固定文字"), Category("自定义")]
public string FixedText
{
get { return fixedText; }
set
{
fixedText = value;
Refresh();
}
} private Font textFont = DefaultFont;
/// <summary>
/// Gets or sets the text font.
/// </summary>
/// <value>The text font.</value>
[Description("值和固定文字字体"), Category("自定义")]
public Font TextFont
{
get { return textFont; }
set
{
textFont = value;
Refresh();
}
} private Color externalRoundColor = Color.FromArgb(, , );
/// <summary>
/// Gets or sets the color of the external round.
/// </summary>
/// <value>The color of the external round.</value>
[Description("外圆颜色"), Category("自定义")]
public Color ExternalRoundColor
{
get { return externalRoundColor; }
set
{
externalRoundColor = value;
Refresh();
}
} private Color insideRoundColor = Color.FromArgb(, , );
/// <summary>
/// Gets or sets the color of the inside round.
/// </summary>
/// <value>The color of the inside round.</value>
[Description("内圆颜色"), Category("自定义")]
public Color InsideRoundColor
{
get { return insideRoundColor; }
set
{
insideRoundColor = value;
Refresh();
}
} private Color boundaryLineColor = Color.FromArgb(, , );
/// <summary>
/// Gets or sets the color of the boundary line.
/// </summary>
/// <value>The color of the boundary line.</value>
[Description("边界线颜色"), Category("自定义")]
public Color BoundaryLineColor
{
get { return boundaryLineColor; }
set
{
boundaryLineColor = value;
Refresh();
}
} private Color scaleColor = Color.FromArgb(, , );
/// <summary>
/// Gets or sets the color of the scale.
/// </summary>
/// <value>The color of the scale.</value>
[Description("刻度颜色"), Category("自定义")]
public Color ScaleColor
{
get { return scaleColor; }
set
{
scaleColor = value;
Refresh();
}
} private Color scaleValueColor = Color.FromArgb(, , );
/// <summary>
/// Gets or sets the color of the scale value.
/// </summary>
/// <value>The color of the scale value.</value>
[Description("刻度值文字颜色"), Category("自定义")]
public Color ScaleValueColor
{
get { return scaleValueColor; }
set
{
scaleValueColor = value;
Refresh();
}
} private Color pointerColor = Color.FromArgb(, , );
/// <summary>
/// Gets or sets the color of the pointer.
/// </summary>
/// <value>The color of the pointer.</value>
[Description("指针颜色"), Category("自定义")]
public Color PointerColor
{
get { return pointerColor; }
set
{
pointerColor = value;
Refresh();
}
} private Color textColor = Color.FromArgb(, , );
/// <summary>
/// Gets or sets the color of the text.
/// </summary>
/// <value>The color of the text.</value>
[Description("值和固定文字颜色"), Category("自定义")]
public Color TextColor
{
get { return textColor; }
set
{
textColor = value;
Refresh();
}
} Rectangle m_rectWorking;

重绘

  protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
var g = e.Graphics;
g.SetGDIHigh(); //外圆
float fltStartAngle = - - (meterDegrees) / + ;
var r1 = new Rectangle(m_rectWorking.Location, new Size(m_rectWorking.Width, m_rectWorking.Width));
g.DrawArc(new Pen(new SolidBrush(externalRoundColor), ), r1, fltStartAngle, meterDegrees);
//内圆
var r2 = new Rectangle(m_rectWorking.Left + (m_rectWorking.Width - m_rectWorking.Width / ) / , m_rectWorking.Top + (m_rectWorking.Width - m_rectWorking.Width / ) / , m_rectWorking.Width / , m_rectWorking.Width / );
g.DrawArc(new Pen(new SolidBrush(insideRoundColor), ), r2, fltStartAngle, meterDegrees); //边界线
if (meterDegrees != )
{
float fltAngle = fltStartAngle - ; float intY = (float)(m_rectWorking.Top + m_rectWorking.Width / - ((m_rectWorking.Width / - m_rectWorking.Width / ) * Math.Sin(Math.PI * (fltAngle / 180.00F))));
float intX = (float)(m_rectWorking.Left + (m_rectWorking.Width / - ((m_rectWorking.Width / - m_rectWorking.Width / ) * Math.Cos(Math.PI * (fltAngle / 180.00F))))); float fltY1 = (float)(m_rectWorking.Top + m_rectWorking.Width / - (m_rectWorking.Width / * Math.Sin(Math.PI * (fltAngle / 180.00F))));
float fltX1 = (float)(m_rectWorking.Left + (m_rectWorking.Width / - (m_rectWorking.Width / * Math.Cos(Math.PI * (fltAngle / 180.00F))))); g.DrawLine(new Pen(new SolidBrush(boundaryLineColor), ), new PointF(intX, intY), new PointF(fltX1, fltY1));
g.DrawLine(new Pen(new SolidBrush(boundaryLineColor), ), new PointF(m_rectWorking.Right - (fltX1 - m_rectWorking.Left), fltY1), new PointF(m_rectWorking.Right - (intX - m_rectWorking.Left), intY));
} //分割线
int _splitCount = splitCount * ;
float fltSplitValue = (float)meterDegrees / (float)_splitCount;
for (int i = ; i <= _splitCount; i++)
{
float fltAngle = (fltStartAngle + fltSplitValue * i - ) % ;
float fltY1 = (float)(m_rectWorking.Top + m_rectWorking.Width / - ((m_rectWorking.Width / ) * Math.Sin(Math.PI * (fltAngle / 180.00F))));
float fltX1 = (float)(m_rectWorking.Left + (m_rectWorking.Width / - ((m_rectWorking.Width / ) * Math.Cos(Math.PI * (fltAngle / 180.00F)))));
float fltY2 = ;
float fltX2 = ;
if (i % == )
{
fltY2 = (float)(m_rectWorking.Top + m_rectWorking.Width / - ((m_rectWorking.Width / - ) * Math.Sin(Math.PI * (fltAngle / 180.00F))));
fltX2 = (float)(m_rectWorking.Left + (m_rectWorking.Width / - ((m_rectWorking.Width / - ) * Math.Cos(Math.PI * (fltAngle / 180.00F)))));
if (!(meterDegrees == && i == _splitCount))
{
decimal decValue = minValue + (maxValue - minValue) / _splitCount * i;
var txtSize = g.MeasureString(decValue.ToString("0.##"), this.Font);
float fltFY1 = (float)(m_rectWorking.Top - txtSize.Height / + m_rectWorking.Width / - ((m_rectWorking.Width / - ) * Math.Sin(Math.PI * (fltAngle / 180.00F))));
float fltFX1 = (float)(m_rectWorking.Left - txtSize.Width / + (m_rectWorking.Width / - ((m_rectWorking.Width / - ) * Math.Cos(Math.PI * (fltAngle / 180.00F)))));
g.DrawString(decValue.ToString("0.##"), Font, new SolidBrush(scaleValueColor), fltFX1, fltFY1);
}
}
else
{
fltY2 = (float)(m_rectWorking.Top + m_rectWorking.Width / - ((m_rectWorking.Width / - ) * Math.Sin(Math.PI * (fltAngle / 180.00F))));
fltX2 = (float)(m_rectWorking.Left + (m_rectWorking.Width / - ((m_rectWorking.Width / - ) * Math.Cos(Math.PI * (fltAngle / 180.00F)))));
}
g.DrawLine(new Pen(new SolidBrush(scaleColor), i % == ? : ), new PointF(fltX1, fltY1), new PointF(fltX2, fltY2));
} //值文字和固定文字
if (textLocation != MeterTextLocation.None)
{
string str = m_value.ToString("0.##");
var txtSize = g.MeasureString(str, textFont);
float fltY = m_rectWorking.Top + m_rectWorking.Width / - txtSize.Height / ;
float fltX = m_rectWorking.Left + m_rectWorking.Width / - txtSize.Width / ;
g.DrawString(str, textFont, new SolidBrush(textColor), new PointF(fltX, fltY)); if (!string.IsNullOrEmpty(fixedText))
{
str = fixedText;
txtSize = g.MeasureString(str, textFont);
fltY = m_rectWorking.Top + m_rectWorking.Width / + txtSize.Height / ;
fltX = m_rectWorking.Left + m_rectWorking.Width / - txtSize.Width / ;
g.DrawString(str, textFont, new SolidBrush(textColor), new PointF(fltX, fltY));
}
} //画指针
g.FillEllipse(new SolidBrush(Color.FromArgb(, pointerColor.R, pointerColor.G, pointerColor.B)), new Rectangle(m_rectWorking.Left + m_rectWorking.Width / - , m_rectWorking.Top + m_rectWorking.Width / - , , ));
g.FillEllipse(Brushes.Red, new Rectangle(m_rectWorking.Left + m_rectWorking.Width / - , m_rectWorking.Top + m_rectWorking.Width / - , , ));
float fltValueAngle = (fltStartAngle + ((float)(m_value - minValue) / (float)(maxValue - minValue)) * (float)meterDegrees - ) % ;
float intValueY1 = (float)(m_rectWorking.Top + m_rectWorking.Width / - ((m_rectWorking.Width / - ) * Math.Sin(Math.PI * (fltValueAngle / 180.00F))));
float intValueX1 = (float)(m_rectWorking.Left + (m_rectWorking.Width / - ((m_rectWorking.Width / - ) * Math.Cos(Math.PI * (fltValueAngle / 180.00F)))));
g.DrawLine(new Pen(new SolidBrush(pointerColor), ), intValueX1, intValueY1, m_rectWorking.Left + m_rectWorking.Width / , m_rectWorking.Top + m_rectWorking.Width / );
}

还有一个显示文字位置的枚举

 /// <summary>
/// Enum MeterTextLocation
/// </summary>
public enum MeterTextLocation
{
/// <summary>
/// The none
/// </summary>
None,
/// <summary>
/// The top
/// </summary>
Top,
/// <summary>
/// The bottom
/// </summary>
Bottom
}

代码就这么多了,看完整代码

 // ***********************************************************************
// Assembly : HZH_Controls
// Created : 2019-09-03
//
// ***********************************************************************
// <copyright file="UCMeter.cs">
// Copyright by Huang Zhenghui(黄正辉) All, QQ group:568015492 QQ:623128629 Email:623128629@qq.com
// </copyright>
//
// Blog: https://www.cnblogs.com/bfyx
// GitHub:https://github.com/kwwwvagaa/NetWinformControl
// gitee:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
//
// If you use this code, please keep this note.
// ***********************************************************************
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.ComponentModel; namespace HZH_Controls.Controls
{
/// <summary>
/// Class UCMeter.
/// Implements the <see cref="System.Windows.Forms.UserControl" />
/// </summary>
/// <seealso cref="System.Windows.Forms.UserControl" />
public class UCMeter : UserControl
{
private int splitCount = ;
/// <summary>
/// Gets or sets the split count.
/// </summary>
/// <value>The split count.</value>
[Description("分隔刻度数量,>1"), Category("自定义")]
public int SplitCount
{
get { return splitCount; }
set
{
if (value < )
return;
splitCount = value;
Refresh();
}
} private int meterDegrees = ;
/// <summary>
/// Gets or sets the meter degrees.
/// </summary>
/// <value>The meter degrees.</value>
[Description("表盘跨度角度,0-360"), Category("自定义")]
public int MeterDegrees
{
get { return meterDegrees; }
set
{
if (value > || value <= )
return;
meterDegrees = value;
Refresh();
}
} private decimal minValue = ;
/// <summary>
/// Gets or sets the minimum value.
/// </summary>
/// <value>The minimum value.</value>
[Description("最小值,<MaxValue"), Category("自定义")]
public decimal MinValue
{
get { return minValue; }
set
{
if (value >= maxValue)
return;
minValue = value;
Refresh();
}
} private decimal maxValue = ;
/// <summary>
/// Gets or sets the maximum value.
/// </summary>
/// <value>The maximum value.</value>
[Description("最大值,>MinValue"), Category("自定义")]
public decimal MaxValue
{
get { return maxValue; }
set
{
if (value <= minValue)
return;
maxValue = value;
Refresh();
}
}
/// <summary>
/// 获取或设置控件显示的文字的字体。
/// </summary>
/// <value>The font.</value>
/// <PermissionSet>
/// <IPermission class="System.Security.Permissions.EnvironmentPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
/// <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
/// <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="UnmanagedCode, ControlEvidence" />
/// <IPermission class="System.Diagnostics.PerformanceCounterPermission, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
/// </PermissionSet>
[Description("刻度字体"), Category("自定义")]
public override Font Font
{
get
{
return base.Font;
}
set
{
base.Font = value;
Refresh();
}
} private decimal m_value = ;
/// <summary>
/// Gets or sets the value.
/// </summary>
/// <value>The value.</value>
[Description("值,>=MinValue并且<=MaxValue"), Category("自定义")]
public decimal Value
{
get { return m_value; }
set
{
if (value < minValue || value > maxValue)
return;
m_value = value;
Refresh();
}
} private MeterTextLocation textLocation = MeterTextLocation.None;
/// <summary>
/// Gets or sets the text location.
/// </summary>
/// <value>The text location.</value>
[Description("值和固定文字显示位置"), Category("自定义")]
public MeterTextLocation TextLocation
{
get { return textLocation; }
set
{
textLocation = value;
Refresh();
}
} private string fixedText;
/// <summary>
/// Gets or sets the fixed text.
/// </summary>
/// <value>The fixed text.</value>
[Description("固定文字"), Category("自定义")]
public string FixedText
{
get { return fixedText; }
set
{
fixedText = value;
Refresh();
}
} private Font textFont = DefaultFont;
/// <summary>
/// Gets or sets the text font.
/// </summary>
/// <value>The text font.</value>
[Description("值和固定文字字体"), Category("自定义")]
public Font TextFont
{
get { return textFont; }
set
{
textFont = value;
Refresh();
}
} private Color externalRoundColor = Color.FromArgb(, , );
/// <summary>
/// Gets or sets the color of the external round.
/// </summary>
/// <value>The color of the external round.</value>
[Description("外圆颜色"), Category("自定义")]
public Color ExternalRoundColor
{
get { return externalRoundColor; }
set
{
externalRoundColor = value;
Refresh();
}
} private Color insideRoundColor = Color.FromArgb(, , );
/// <summary>
/// Gets or sets the color of the inside round.
/// </summary>
/// <value>The color of the inside round.</value>
[Description("内圆颜色"), Category("自定义")]
public Color InsideRoundColor
{
get { return insideRoundColor; }
set
{
insideRoundColor = value;
Refresh();
}
} private Color boundaryLineColor = Color.FromArgb(, , );
/// <summary>
/// Gets or sets the color of the boundary line.
/// </summary>
/// <value>The color of the boundary line.</value>
[Description("边界线颜色"), Category("自定义")]
public Color BoundaryLineColor
{
get { return boundaryLineColor; }
set
{
boundaryLineColor = value;
Refresh();
}
} private Color scaleColor = Color.FromArgb(, , );
/// <summary>
/// Gets or sets the color of the scale.
/// </summary>
/// <value>The color of the scale.</value>
[Description("刻度颜色"), Category("自定义")]
public Color ScaleColor
{
get { return scaleColor; }
set
{
scaleColor = value;
Refresh();
}
} private Color scaleValueColor = Color.FromArgb(, , );
/// <summary>
/// Gets or sets the color of the scale value.
/// </summary>
/// <value>The color of the scale value.</value>
[Description("刻度值文字颜色"), Category("自定义")]
public Color ScaleValueColor
{
get { return scaleValueColor; }
set
{
scaleValueColor = value;
Refresh();
}
} private Color pointerColor = Color.FromArgb(, , );
/// <summary>
/// Gets or sets the color of the pointer.
/// </summary>
/// <value>The color of the pointer.</value>
[Description("指针颜色"), Category("自定义")]
public Color PointerColor
{
get { return pointerColor; }
set
{
pointerColor = value;
Refresh();
}
} private Color textColor = Color.FromArgb(, , );
/// <summary>
/// Gets or sets the color of the text.
/// </summary>
/// <value>The color of the text.</value>
[Description("值和固定文字颜色"), Category("自定义")]
public Color TextColor
{
get { return textColor; }
set
{
textColor = value;
Refresh();
}
} Rectangle m_rectWorking;
public UCMeter()
{
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.DoubleBuffer, true);
this.SetStyle(ControlStyles.ResizeRedraw, true);
this.SetStyle(ControlStyles.Selectable, true);
this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
this.SetStyle(ControlStyles.UserPaint, true);
this.SizeChanged += UCMeter1_SizeChanged;
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.Size = new Size(, );
} void UCMeter1_SizeChanged(object sender, EventArgs e)
{
m_rectWorking = new Rectangle(, , this.Width - , this.Height - );
} protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
var g = e.Graphics;
g.SetGDIHigh(); //外圆
float fltStartAngle = - - (meterDegrees) / + ;
var r1 = new Rectangle(m_rectWorking.Location, new Size(m_rectWorking.Width, m_rectWorking.Width));
g.DrawArc(new Pen(new SolidBrush(externalRoundColor), ), r1, fltStartAngle, meterDegrees);
//内圆
var r2 = new Rectangle(m_rectWorking.Left + (m_rectWorking.Width - m_rectWorking.Width / ) / , m_rectWorking.Top + (m_rectWorking.Width - m_rectWorking.Width / ) / , m_rectWorking.Width / , m_rectWorking.Width / );
g.DrawArc(new Pen(new SolidBrush(insideRoundColor), ), r2, fltStartAngle, meterDegrees); //边界线
if (meterDegrees != )
{
float fltAngle = fltStartAngle - ; float intY = (float)(m_rectWorking.Top + m_rectWorking.Width / - ((m_rectWorking.Width / - m_rectWorking.Width / ) * Math.Sin(Math.PI * (fltAngle / 180.00F))));
float intX = (float)(m_rectWorking.Left + (m_rectWorking.Width / - ((m_rectWorking.Width / - m_rectWorking.Width / ) * Math.Cos(Math.PI * (fltAngle / 180.00F))))); float fltY1 = (float)(m_rectWorking.Top + m_rectWorking.Width / - (m_rectWorking.Width / * Math.Sin(Math.PI * (fltAngle / 180.00F))));
float fltX1 = (float)(m_rectWorking.Left + (m_rectWorking.Width / - (m_rectWorking.Width / * Math.Cos(Math.PI * (fltAngle / 180.00F))))); g.DrawLine(new Pen(new SolidBrush(boundaryLineColor), ), new PointF(intX, intY), new PointF(fltX1, fltY1));
g.DrawLine(new Pen(new SolidBrush(boundaryLineColor), ), new PointF(m_rectWorking.Right - (fltX1 - m_rectWorking.Left), fltY1), new PointF(m_rectWorking.Right - (intX - m_rectWorking.Left), intY));
} //分割线
int _splitCount = splitCount * ;
float fltSplitValue = (float)meterDegrees / (float)_splitCount;
for (int i = ; i <= _splitCount; i++)
{
float fltAngle = (fltStartAngle + fltSplitValue * i - ) % ;
float fltY1 = (float)(m_rectWorking.Top + m_rectWorking.Width / - ((m_rectWorking.Width / ) * Math.Sin(Math.PI * (fltAngle / 180.00F))));
float fltX1 = (float)(m_rectWorking.Left + (m_rectWorking.Width / - ((m_rectWorking.Width / ) * Math.Cos(Math.PI * (fltAngle / 180.00F)))));
float fltY2 = ;
float fltX2 = ;
if (i % == )
{
fltY2 = (float)(m_rectWorking.Top + m_rectWorking.Width / - ((m_rectWorking.Width / - ) * Math.Sin(Math.PI * (fltAngle / 180.00F))));
fltX2 = (float)(m_rectWorking.Left + (m_rectWorking.Width / - ((m_rectWorking.Width / - ) * Math.Cos(Math.PI * (fltAngle / 180.00F)))));
if (!(meterDegrees == && i == _splitCount))
{
decimal decValue = minValue + (maxValue - minValue) / _splitCount * i;
var txtSize = g.MeasureString(decValue.ToString("0.##"), this.Font);
float fltFY1 = (float)(m_rectWorking.Top - txtSize.Height / + m_rectWorking.Width / - ((m_rectWorking.Width / - ) * Math.Sin(Math.PI * (fltAngle / 180.00F))));
float fltFX1 = (float)(m_rectWorking.Left - txtSize.Width / + (m_rectWorking.Width / - ((m_rectWorking.Width / - ) * Math.Cos(Math.PI * (fltAngle / 180.00F)))));
g.DrawString(decValue.ToString("0.##"), Font, new SolidBrush(scaleValueColor), fltFX1, fltFY1);
}
}
else
{
fltY2 = (float)(m_rectWorking.Top + m_rectWorking.Width / - ((m_rectWorking.Width / - ) * Math.Sin(Math.PI * (fltAngle / 180.00F))));
fltX2 = (float)(m_rectWorking.Left + (m_rectWorking.Width / - ((m_rectWorking.Width / - ) * Math.Cos(Math.PI * (fltAngle / 180.00F)))));
}
g.DrawLine(new Pen(new SolidBrush(scaleColor), i % == ? : ), new PointF(fltX1, fltY1), new PointF(fltX2, fltY2));
} //值文字和固定文字
if (textLocation != MeterTextLocation.None)
{
string str = m_value.ToString("0.##");
var txtSize = g.MeasureString(str, textFont);
float fltY = m_rectWorking.Top + m_rectWorking.Width / - txtSize.Height / ;
float fltX = m_rectWorking.Left + m_rectWorking.Width / - txtSize.Width / ;
g.DrawString(str, textFont, new SolidBrush(textColor), new PointF(fltX, fltY)); if (!string.IsNullOrEmpty(fixedText))
{
str = fixedText;
txtSize = g.MeasureString(str, textFont);
fltY = m_rectWorking.Top + m_rectWorking.Width / + txtSize.Height / ;
fltX = m_rectWorking.Left + m_rectWorking.Width / - txtSize.Width / ;
g.DrawString(str, textFont, new SolidBrush(textColor), new PointF(fltX, fltY));
}
} //画指针
g.FillEllipse(new SolidBrush(Color.FromArgb(, pointerColor.R, pointerColor.G, pointerColor.B)), new Rectangle(m_rectWorking.Left + m_rectWorking.Width / - , m_rectWorking.Top + m_rectWorking.Width / - , , ));
g.FillEllipse(Brushes.Red, new Rectangle(m_rectWorking.Left + m_rectWorking.Width / - , m_rectWorking.Top + m_rectWorking.Width / - , , ));
float fltValueAngle = (fltStartAngle + ((float)(m_value - minValue) / (float)(maxValue - minValue)) * (float)meterDegrees - ) % ;
float intValueY1 = (float)(m_rectWorking.Top + m_rectWorking.Width / - ((m_rectWorking.Width / - ) * Math.Sin(Math.PI * (fltValueAngle / 180.00F))));
float intValueX1 = (float)(m_rectWorking.Left + (m_rectWorking.Width / - ((m_rectWorking.Width / - ) * Math.Cos(Math.PI * (fltValueAngle / 180.00F)))));
g.DrawLine(new Pen(new SolidBrush(pointerColor), ), intValueX1, intValueY1, m_rectWorking.Left + m_rectWorking.Width / , m_rectWorking.Top + m_rectWorking.Width / );
}
} /// <summary>
/// Enum MeterTextLocation
/// </summary>
public enum MeterTextLocation
{
/// <summary>
/// The none
/// </summary>
None,
/// <summary>
/// The top
/// </summary>
Top,
/// <summary>
/// The bottom
/// </summary>
Bottom
}
}

最后的话

如果你喜欢的话,请到 https://gitee.com/kwwwvagaa/net_winform_custom_control 点个星星吧

(五十四)c#Winform自定义控件-仪表盘的更多相关文章

  1. (五十)c#Winform自定义控件-滑块

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...

  2. 第三百五十四节,Python分布式爬虫打造搜索引擎Scrapy精讲—数据收集(Stats Collection)

    第三百五十四节,Python分布式爬虫打造搜索引擎Scrapy精讲—数据收集(Stats Collection) Scrapy提供了方便的收集数据的机制.数据以key/value方式存储,值大多是计数 ...

  3. “全栈2019”Java第五十四章:多态详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  4. 孤荷凌寒自学python第五十四天使用python来删除Firebase数据库中的文档

    孤荷凌寒自学python第五十四天使用python来删除Firebase数据库中的文档 (完整学习过程屏幕记录视频地址在文末) 今天继续研究Firebase数据库,利用google免费提供的这个数据库 ...

  5. (三十)c#Winform自定义控件-文本框(三)

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...

  6. abp(net core)+easyui+efcore实现仓储管理系统——出库管理之五(五十四)

    abp(net core)+easyui+efcore实现仓储管理系统目录 abp(net core)+easyui+efcore实现仓储管理系统--ABP总体介绍(一) abp(net core)+ ...

  7. (二十)c#Winform自定义控件-有后退的窗体

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...

  8. (四十)c#Winform自定义控件-开关-HZHControls

    官网 http://www.hzhcontrols.com 前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kww ...

  9. 五十四、SAP中LVC表格每列的宽度自适应

    一.之前我们的LVC表格输出的界面,有些列太宽余留空白区块太多,有些列则显示不全还带省略号等 二.我们来到'REUSE_ALV_GRID_DISPLAY_LVC'的模块中,查看他的属性 三.我们查看L ...

随机推荐

  1. Clock Crossing Adapter传输效率分析 (Latency增加,传输效率降低)

    原创By DeeZeng [ Intel FPGA笔记 ] 在用Nios II测试 DDR3时候发现一个现象 (测试为:写全片,读全片+比对) 用单独的PLL产生时钟(200MHz)驱动 Nios I ...

  2. spring与mybatis整合(扫描Mapper接口)

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" ...

  3. python模块知识二 random -- 随机模块、序列化 、os模块、sys -- 系统模块

    4.random -- 随机模块 a-z:97 ~ 122 A-Z :65 ~ 90 import random #浮点数 print(random.random())#0~1,不可指定 print( ...

  4. T-SQL 小全

    --====================================================== ----数据库概念:创建.删除.使用数据库 ----================= ...

  5. 史上最强Java开发环境搭建

    在项目产品开发中,开发环境搭建是软件开发的首要阶段,也是必须阶段,只有开发环境搭建好了,方可进行开发,良好的开发环境搭建,为后续的开发工作带来极大便利. 对于大公司来说,软件开发环境搭建工作一般是由运 ...

  6. java类加载器-Bootstrap、 ExtClassLoader、 AppClassLoader的关系

    1. 简单介绍 Bootstrap. ExtClassLoader.  AppClassLoader是java最根正苗红的类加载器. Bootstrap是本地代码编写的(例如C), ExtClassL ...

  7. hdu 6406 Taotao Picks Apples (线段树)

    Problem Description There is an apple tree in front of Taotao's house. When autumn comes, n apples o ...

  8. Jenkins 持续集成持续发布使用搭建基础

    一.环境搭建基础 1.持续集成.持续交付.持续部署概念 ①.集成: 是指软件多人研发的部分软件代码整合交付,以便尽早发现个人开发部分的问题:持续集成:强调开发人员提交了新代码之后,立刻进行构建(单元) ...

  9. istio入门教程

    广告 | kubernetes各版本离线安装包 安装 安装k8s 强势插播广告 三步安装,不多说 安装helm, 推荐生产环境用helm安装,可以调参 release地址 如我使用的2.9.1版本 y ...

  10. 消息中间件-activemq实战之消息持久化(六)

    对于activemq消息的持久化我们在第二节的时候就简单介绍过,今天我们详细的来分析一下activemq的持久化过程以及持久化插件.在生产环境中为确保消息的可靠性,我们肯定的面临持久化消息的问题,今天 ...