c# Winform自定义控件-仪表盘功能
程序员文章站
2022-03-11 08:49:16
前提
入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。
github:https://github.com/kwwwvagaa/netwinf...
前提
入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。
github:https://github.com/kwwwvagaa/netwinformcontrol
码云:
nuget
install-package hzh_controls
目录
用处及效果
准备工作
依然使用gdi+画的,不懂的话就百度一下吧
另外主要用到了三角函数,如果不懂,可以向初中的数学老师再问问(你也可以百度一下)
开始
添加一个类ucmeter 继承 usercontrol
首先添加一个需要控制的属性
private int splitcount = 10; /// <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 < 1) return; splitcount = value; refresh(); } } private int meterdegrees = 150; /// <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 > 360 || value <= 0) return; meterdegrees = value; refresh(); } } private decimal minvalue = 0; /// <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 = 100; /// <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 = 0; /// <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(255, 77, 59); /// <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(255, 77, 59); /// <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(255, 77, 59); /// <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(255, 77, 59); /// <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(255, 77, 59); /// <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(255, 77, 59); /// <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(255, 77, 59); /// <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 = -90 - (meterdegrees) / 2 + 360; var r1 = new rectangle(m_rectworking.location, new size(m_rectworking.width, m_rectworking.width)); g.drawarc(new pen(new solidbrush(externalroundcolor), 1), r1, fltstartangle, meterdegrees); //内圆 var r2 = new rectangle(m_rectworking.left + (m_rectworking.width - m_rectworking.width / 4) / 2, m_rectworking.top + (m_rectworking.width - m_rectworking.width / 4) / 2, m_rectworking.width / 4, m_rectworking.width / 4); g.drawarc(new pen(new solidbrush(insideroundcolor), 1), r2, fltstartangle, meterdegrees); //边界线 if (meterdegrees != 360) { float fltangle = fltstartangle - 180; float inty = (float)(m_rectworking.top + m_rectworking.width / 2 - ((m_rectworking.width / 2 - m_rectworking.width / 8) * math.sin(math.pi * (fltangle / 180.00f)))); float intx = (float)(m_rectworking.left + (m_rectworking.width / 2 - ((m_rectworking.width / 2 - m_rectworking.width / 8) * math.cos(math.pi * (fltangle / 180.00f))))); float flty1 = (float)(m_rectworking.top + m_rectworking.width / 2 - (m_rectworking.width / 8 * math.sin(math.pi * (fltangle / 180.00f)))); float fltx1 = (float)(m_rectworking.left + (m_rectworking.width / 2 - (m_rectworking.width / 8 * math.cos(math.pi * (fltangle / 180.00f))))); g.drawline(new pen(new solidbrush(boundarylinecolor), 1), new pointf(intx, inty), new pointf(fltx1, flty1)); g.drawline(new pen(new solidbrush(boundarylinecolor), 1), new pointf(m_rectworking.right - (fltx1 - m_rectworking.left), flty1), new pointf(m_rectworking.right - (intx - m_rectworking.left), inty)); } //分割线 int _splitcount = splitcount * 2; float fltsplitvalue = (float)meterdegrees / (float)_splitcount; for (int i = 0; i <= _splitcount; i++) { float fltangle = (fltstartangle + fltsplitvalue * i - 180) % 360; float flty1 = (float)(m_rectworking.top + m_rectworking.width / 2 - ((m_rectworking.width / 2) * math.sin(math.pi * (fltangle / 180.00f)))); float fltx1 = (float)(m_rectworking.left + (m_rectworking.width / 2 - ((m_rectworking.width / 2) * math.cos(math.pi * (fltangle / 180.00f))))); float flty2 = 0; float fltx2 = 0; if (i % 2 == 0) { flty2 = (float)(m_rectworking.top + m_rectworking.width / 2 - ((m_rectworking.width / 2 - 10) * math.sin(math.pi * (fltangle / 180.00f)))); fltx2 = (float)(m_rectworking.left + (m_rectworking.width / 2 - ((m_rectworking.width / 2 - 10) * math.cos(math.pi * (fltangle / 180.00f))))); if (!(meterdegrees == 360 && 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 / 2 + m_rectworking.width / 2 - ((m_rectworking.width / 2 - 20) * math.sin(math.pi * (fltangle / 180.00f)))); float fltfx1 = (float)(m_rectworking.left - txtsize.width / 2 + (m_rectworking.width / 2 - ((m_rectworking.width / 2 - 20) * 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 / 2 - ((m_rectworking.width / 2 - 5) * math.sin(math.pi * (fltangle / 180.00f)))); fltx2 = (float)(m_rectworking.left + (m_rectworking.width / 2 - ((m_rectworking.width / 2 - 5) * math.cos(math.pi * (fltangle / 180.00f))))); } g.drawline(new pen(new solidbrush(scalecolor), i % 2 == 0 ? 2 : 1), 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 / 4 - txtsize.height / 2; float fltx = m_rectworking.left + m_rectworking.width / 2 - txtsize.width / 2; 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 / 4 + txtsize.height / 2; fltx = m_rectworking.left + m_rectworking.width / 2 - txtsize.width / 2; g.drawstring(str, textfont, new solidbrush(textcolor), new pointf(fltx, flty)); } } //画指针 g.fillellipse(new solidbrush(color.fromargb(100, pointercolor.r, pointercolor.g, pointercolor.b)), new rectangle(m_rectworking.left + m_rectworking.width / 2 - 10, m_rectworking.top + m_rectworking.width / 2 - 10, 20, 20)); g.fillellipse(brushes.red, new rectangle(m_rectworking.left + m_rectworking.width / 2 - 5, m_rectworking.top + m_rectworking.width / 2 - 5, 10, 10)); float fltvalueangle = (fltstartangle + ((float)(m_value - minvalue) / (float)(maxvalue - minvalue)) * (float)meterdegrees - 180) % 360; float intvaluey1 = (float)(m_rectworking.top + m_rectworking.width / 2 - ((m_rectworking.width / 2 - 30) * math.sin(math.pi * (fltvalueangle / 180.00f)))); float intvaluex1 = (float)(m_rectworking.left + (m_rectworking.width / 2 - ((m_rectworking.width / 2 - 30) * math.cos(math.pi * (fltvalueangle / 180.00f))))); g.drawline(new pen(new solidbrush(pointercolor), 3), intvaluex1, intvaluey1, m_rectworking.left + m_rectworking.width / 2, m_rectworking.top + m_rectworking.width / 2); }
还有一个显示文字位置的枚举
/// <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 = 10; /// <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 < 1) return; splitcount = value; refresh(); } } private int meterdegrees = 150; /// <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 > 360 || value <= 0) return; meterdegrees = value; refresh(); } } private decimal minvalue = 0; /// <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 = 100; /// <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 = 0; /// <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(255, 77, 59); /// <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(255, 77, 59); /// <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(255, 77, 59); /// <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(255, 77, 59); /// <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(255, 77, 59); /// <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(255, 77, 59); /// <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(255, 77, 59); /// <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(350, 200); } void ucmeter1_sizechanged(object sender, eventargs e) { m_rectworking = new rectangle(10, 10, this.width - 20, this.height - 20); } protected override void onpaint(painteventargs e) { base.onpaint(e); var g = e.graphics; g.setgdihigh(); //外圆 float fltstartangle = -90 - (meterdegrees) / 2 + 360; var r1 = new rectangle(m_rectworking.location, new size(m_rectworking.width, m_rectworking.width)); g.drawarc(new pen(new solidbrush(externalroundcolor), 1), r1, fltstartangle, meterdegrees); //内圆 var r2 = new rectangle(m_rectworking.left + (m_rectworking.width - m_rectworking.width / 4) / 2, m_rectworking.top + (m_rectworking.width - m_rectworking.width / 4) / 2, m_rectworking.width / 4, m_rectworking.width / 4); g.drawarc(new pen(new solidbrush(insideroundcolor), 1), r2, fltstartangle, meterdegrees); //边界线 if (meterdegrees != 360) { float fltangle = fltstartangle - 180; float inty = (float)(m_rectworking.top + m_rectworking.width / 2 - ((m_rectworking.width / 2 - m_rectworking.width / 8) * math.sin(math.pi * (fltangle / 180.00f)))); float intx = (float)(m_rectworking.left + (m_rectworking.width / 2 - ((m_rectworking.width / 2 - m_rectworking.width / 8) * math.cos(math.pi * (fltangle / 180.00f))))); float flty1 = (float)(m_rectworking.top + m_rectworking.width / 2 - (m_rectworking.width / 8 * math.sin(math.pi * (fltangle / 180.00f)))); float fltx1 = (float)(m_rectworking.left + (m_rectworking.width / 2 - (m_rectworking.width / 8 * math.cos(math.pi * (fltangle / 180.00f))))); g.drawline(new pen(new solidbrush(boundarylinecolor), 1), new pointf(intx, inty), new pointf(fltx1, flty1)); g.drawline(new pen(new solidbrush(boundarylinecolor), 1), new pointf(m_rectworking.right - (fltx1 - m_rectworking.left), flty1), new pointf(m_rectworking.right - (intx - m_rectworking.left), inty)); } //分割线 int _splitcount = splitcount * 2; float fltsplitvalue = (float)meterdegrees / (float)_splitcount; for (int i = 0; i <= _splitcount; i++) { float fltangle = (fltstartangle + fltsplitvalue * i - 180) % 360; float flty1 = (float)(m_rectworking.top + m_rectworking.width / 2 - ((m_rectworking.width / 2) * math.sin(math.pi * (fltangle / 180.00f)))); float fltx1 = (float)(m_rectworking.left + (m_rectworking.width / 2 - ((m_rectworking.width / 2) * math.cos(math.pi * (fltangle / 180.00f))))); float flty2 = 0; float fltx2 = 0; if (i % 2 == 0) { flty2 = (float)(m_rectworking.top + m_rectworking.width / 2 - ((m_rectworking.width / 2 - 10) * math.sin(math.pi * (fltangle / 180.00f)))); fltx2 = (float)(m_rectworking.left + (m_rectworking.width / 2 - ((m_rectworking.width / 2 - 10) * math.cos(math.pi * (fltangle / 180.00f))))); if (!(meterdegrees == 360 && 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 / 2 + m_rectworking.width / 2 - ((m_rectworking.width / 2 - 20) * math.sin(math.pi * (fltangle / 180.00f)))); float fltfx1 = (float)(m_rectworking.left - txtsize.width / 2 + (m_rectworking.width / 2 - ((m_rectworking.width / 2 - 20) * 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 / 2 - ((m_rectworking.width / 2 - 5) * math.sin(math.pi * (fltangle / 180.00f)))); fltx2 = (float)(m_rectworking.left + (m_rectworking.width / 2 - ((m_rectworking.width / 2 - 5) * math.cos(math.pi * (fltangle / 180.00f))))); } g.drawline(new pen(new solidbrush(scalecolor), i % 2 == 0 ? 2 : 1), 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 / 4 - txtsize.height / 2; float fltx = m_rectworking.left + m_rectworking.width / 2 - txtsize.width / 2; 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 / 4 + txtsize.height / 2; fltx = m_rectworking.left + m_rectworking.width / 2 - txtsize.width / 2; g.drawstring(str, textfont, new solidbrush(textcolor), new pointf(fltx, flty)); } } //画指针 g.fillellipse(new solidbrush(color.fromargb(100, pointercolor.r, pointercolor.g, pointercolor.b)), new rectangle(m_rectworking.left + m_rectworking.width / 2 - 10, m_rectworking.top + m_rectworking.width / 2 - 10, 20, 20)); g.fillellipse(brushes.red, new rectangle(m_rectworking.left + m_rectworking.width / 2 - 5, m_rectworking.top + m_rectworking.width / 2 - 5, 10, 10)); float fltvalueangle = (fltstartangle + ((float)(m_value - minvalue) / (float)(maxvalue - minvalue)) * (float)meterdegrees - 180) % 360; float intvaluey1 = (float)(m_rectworking.top + m_rectworking.width / 2 - ((m_rectworking.width / 2 - 30) * math.sin(math.pi * (fltvalueangle / 180.00f)))); float intvaluex1 = (float)(m_rectworking.left + (m_rectworking.width / 2 - ((m_rectworking.width / 2 - 30) * math.cos(math.pi * (fltvalueangle / 180.00f))))); g.drawline(new pen(new solidbrush(pointercolor), 3), intvaluex1, intvaluey1, m_rectworking.left + m_rectworking.width / 2, m_rectworking.top + m_rectworking.width / 2); } } /// <summary> /// enum metertextlocation /// </summary> public enum metertextlocation { /// <summary> /// the none /// </summary> none, /// <summary> /// the top /// </summary> top, /// <summary> /// the bottom /// </summary> bottom } }
最后的话
如果你喜欢的话,请到 点个星星吧
总结
以上所述是小编给大家介绍的c# winform自定义控件-仪表盘功能,希望对大家有所帮助
上一篇: 正则表达式之文本模式的匹配和查找
下一篇: c# 类成员的可访问性代码详解