欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C# GDI绘制仪表盘(纯代码实现)

程序员文章站 2022-04-14 11:01:10
效果实现如下: ......
纯代码实现gdi绘制仪表盘,效果在代码下面。

public partial class halfdashboarduc : usercontrol { /// <summary> /// 仪表盘背景图片 /// </summary> private image dashboardimage; /// <summary> /// 定义该仪表盘画布的最大值为371 /// </summary> private int maxsize = 371; /// <summary> /// 仪表盘画布的放大倍数,默认1 /// </summary> private float multiple = 1; /// <summary> /// 定义该仪表盘的直径大小 /// </summary> private float diameter; /// <summary> /// 每个间隔值 /// </summary> private int intervalvalue; /// <summary> /// 仪表盘显示的最小值,默认为0 /// </summary> private float minvalue = 0; /// <summary> /// 仪表盘显示的最小值 /// </summary> [category("wyl")] [description("仪表盘显示的最小值")] public float minvalue { get { return minvalue; } set { if (value >= maxvalue) { messagebox.show("最小值不能超过最大值!", "警告", messageboxbuttons.ok, messageboxicon.warning); minvalue = 0; } else { minvalue = value; //drawbackimage(); } } } /// <summary> /// 仪表盘上显示的最大值,默认123。 /// </summary> private float maxvalue = 123; /// <summary> /// 仪表盘上显示的最大值 /// </summary> [category("wyl")] [description("仪表盘上显示的最大值")] public float maxvalue { get { return maxvalue; } set { if (value <= minvalue) { messagebox.show("最大值不能低于最小值!", "警告", messageboxbuttons.ok, messageboxicon.warning); maxvalue = 123; } else { maxvalue = value; //drawbackimage(); } } } // <summary> /// 仪表盘变换的值,默认为0; /// </summary> private float changevalue = 0; /// <summary> /// 仪表盘变换的值 /// </summary> public float changevalue { get { return changevalue; } set { changevalue = value; } } /// <summary> /// 指针颜色 /// </summary> private color pincolor = color.fromargb(191, 148, 28); public color pincolor { get { return pincolor; } set { pincolor = value; } } public halfdashboarduc() { initializecomponent(); //双缓存防止屏幕抖动 this.setstyle(controlstyles.optimizeddoublebuffer | controlstyles.allpaintinginwmpaint | controlstyles.doublebuffer, true); this.setstyle(controlstyles.userpaint, true); this.updatestyles(); //设置背景颜色为透明 this.backcolor = color.transparent; } //private int uintfontsize = 40; /// <summary> /// 初始化仪表盘画布 /// </summary> private void initialcanvas() { //对比控件的长高,以最小值为仪表盘的半径 if (this.width > 2 * this.height) { diameter = 2 * this.height - 15; } else { diameter = this.width - 15; } multiple = (float)diameter / maxsize;//计算仪表盘放大倍数 //如果半径大于仪表盘的最大值,则设定放大倍数为默认值 if (multiple > 1) { multiple = 1; diameter = maxsize; } intervalvalue = (int)((maxvalue - minvalue) / 3);//计算每个间隔之间的值 } /// <summary> /// 画底图 /// </summary> private void drawbackimage() { bitmap bit = new bitmap(this.width, this.height); graphics gp = graphics.fromimage(bit); gp.smoothingmode = system.drawing.drawing2d.smoothingmode.highquality; float radius = diameter / 2;//半径 float cerx = this.width / 2; float cery = this.height / 2 + radius / 2 - 10 * multiple; //float cery = this.height - 20 ; gp.translatetransform(cerx, cery);//以中心点为画布的起始点 //gp.drawpie(new pen(new solidbrush(color.fromargb(19,20,25)),3), -radius, -radius, diameter, diameter, 175, 190); gp.drawarc(new pen(new solidbrush(color.fromargb(19, 20, 25)), 3), -radius, -radius, diameter, diameter, 175, 190); float x1 = (float)((radius) * math.cos(175 * math.pi / 180)); float y1 = (float)((radius) * math.sin(175 * math.pi / 180)); float x2 = (float)((radius) * math.cos(5 * math.pi / 180)); float y2 = (float)((radius) * math.sin(5 * math.pi / 180)); gp.drawline(new pen(new solidbrush(color.fromargb(19, 20, 25)), 3), x1, y1, x2, y2); //gp.drawellipse(new pen(brushes.red), -5, -5, 10, 10); float startrad = 180;//起始角度 float sweepshot = 0;//旋转角度 //gp.drawline(new pen(brushes.red), -radius, 0, -(radius - 10), 0); for (int i = 0; i <= 30; i++) { double rad = (sweepshot + startrad) * math.pi / 180; if (i % 5 == 0) { float px1 = (float)((radius - 5 ) * math.cos(rad)); float py1 = (float)((radius - 5 ) * math.sin(rad)); float px2 = (float)((radius - 15) * math.cos(rad)); float py2 = (float)((radius - 15) * math.sin(rad)); gp.drawline(new pen(new solidbrush(color.fromargb(122, 179, 222)), 2), px1, py1, px2, py2); } else { float px1 = (float)((radius - 5 ) * math.cos(rad)); float py1 = (float)((radius - 5 ) * math.sin(rad)); float px2 = (float)((radius - 10 ) * math.cos(rad)); float py2 = (float)((radius - 10 ) * math.sin(rad)); gp.drawline(new pen(new solidbrush(color.fromargb(77, 88, 124)), 1), px1, py1, px2, py2); } sweepshot += 6; } //刻度字体 font scalefont = new font("宋体", 9, fontstyle.bold); startrad = 270;//起始角度 sweepshot = 0;//旋转角度 color c1 = color.fromargb(0, 192, 0); for (int i = 0; i < 4; i++) { int tempvalue = i * intervalvalue; sizef tempsf = gp.measurestring(tempvalue.tostring(), scalefont); //计算角度值 double rad = (sweepshot + startrad) * math.pi / 180; float px = (float)((radius - 18) * math.cos(rad)); float py = (float)((radius - 18) * math.sin(rad)); if (sweepshot == 0) { gp.drawstring(tempvalue.tostring(), scalefont, brushes.wheat, px - tempsf.width / 2, py); } else if (sweepshot == 30) { gp.drawstring(tempvalue.tostring(), scalefont, new solidbrush(c1), px - tempsf.width + 5 * multiple, py - tempsf.height / 2 + 10 * multiple); } else if (sweepshot == 60) { gp.drawstring(tempvalue.tostring(), scalefont, new solidbrush(c1), px - tempsf.width, py - tempsf.height / 2 + 5 * multiple); } else if (sweepshot == 90) { gp.drawstring(tempvalue.tostring(), scalefont, new solidbrush(c1), px - tempsf.width, py - tempsf.height / 2); } //else if (sweepshot == 120) //{ // gp.drawstring(tempvalue.tostring(), scalefont, new solidbrush(c1), px - tempsf.width, py - tempsf.height / 2); //} sweepshot += 30; } startrad = 270;//起始角度 sweepshot = 0;//旋转角度 for (int i = 0; i < 4; i++) { int tempvalue = -i * intervalvalue; sizef tempsf = gp.measurestring(tempvalue.tostring(), scalefont); //计算角度值 double rad = (sweepshot + startrad) * math.pi / 180; float px = (float)((radius - 18 * multiple) * math.cos(rad)); float py = (float)((radius - 18 * multiple) * math.sin(rad)); if (sweepshot == -30) { gp.drawstring(tempvalue.tostring(), scalefont, brushes.red, px, py + tempsf.height / 2); } else if (sweepshot == -60) { gp.drawstring(tempvalue.tostring(), scalefont, brushes.red, px + tempsf.width / 2 - 10 * multiple, py + tempsf.height / 2 - 5 * multiple); } else if (sweepshot == -90) { gp.drawstring(tempvalue.tostring(), scalefont, brushes.red, px + tempsf.width/2 , py - tempsf.height / 2); } sweepshot -= 30; } gp.dispose(); this.backgroundimage = bit; } /// <summary> /// 画图 /// </summary> /// <param name="g"></param> private void drawpin(graphics g) { bitmap bit = new bitmap(this.width, this.height); graphics gp = graphics.fromimage(bit); gp.smoothingmode = system.drawing.drawing2d.smoothingmode.highquality; float radius = diameter / 2;//半径 float startrad = 270;//起始角度 float sweepshot = (float)(changevalue / maxvalue * 90);//旋转角度 float cerx = this.width / 2; float cery = this.height / 2 + radius / 2 - 10 * multiple; gp.translatetransform(cerx, cery);//以中心点为画布的起始点 //gp.drawellipse(new pen(pincolor, 1), -5, -5, 10, 10);//画中心圆圈 double rad = (sweepshot + startrad) * math.pi / 180;//计算角度 float px = (float)((radius - 15) * math.cos(rad)); float py = (float)((radius - 15) * math.sin(rad)); pointf[] pf = new pointf[] { new pointf(0, -radius + 15), new pointf(-4, 0), new pointf(4, 0) }; gp.rotatetransform(sweepshot); //pointf[] pf = new pointf[] { new pointf(px, py), new pointf(-4, 0), new pointf(4, 0) }; gp.fillpolygon(new solidbrush(pincolor), pf); //gp.drawline(new pen(new solidbrush(pincolor), 3f), 0, 0, px, py); g.drawimage(bit, 0, 0); gp.dispose(); } private void halfdashboarduc_load(object sender, eventargs e) { initialcanvas(); drawbackimage(); } private void halfdashboarduc_paint(object sender, painteventargs e) { drawpin(e.graphics); } private void halfdashboarduc_resize(object sender, eventargs e) { initialcanvas(); drawbackimage(); } }

效果实现如下:

C# GDI绘制仪表盘(纯代码实现)

C# GDI绘制仪表盘(纯代码实现)