1. 首先来个金属仪表盘图
  1.  
  1. 金属仪表盘、车载仪表盘 源代码下载
  1. 纯代码实现GDI绘制仪表盘,效果在代码下面。
  2.  
  3.  
  4. public partial class HalfDashboardUc : UserControl
  5. {
  6. /// <summary>
  7. /// 仪表盘背景图片
  8. /// </summary>
  9. private Image dashboardImage;
  10.  
  11. /// <summary>
  12. /// 定义该仪表盘画布的最大值为371
  13. /// </summary>
  14. private int maxSize = ;
  15.  
  16. /// <summary>
  17. /// 仪表盘画布的放大倍数,默认1
  18. /// </summary>
  19. private float multiple = ;
  20.  
  21. /// <summary>
  22. /// 定义该仪表盘的直径大小
  23. /// </summary>
  24. private float diameter;
  25.  
  26. /// <summary>
  27. /// 每个间隔值
  28. /// </summary>
  29. private int intervalValue;
  30.  
  31. /// <summary>
  32. /// 仪表盘显示的最小值,默认为0
  33. /// </summary>
  34. private float minValue = ;
  35.  
  36. /// <summary>
  37. /// 仪表盘显示的最小值
  38. /// </summary>
  39. [Category("wyl")]
  40. [Description("仪表盘显示的最小值")]
  41. public float MinValue
  42. {
  43. get
  44. {
  45. return minValue;
  46. }
  47. set
  48. {
  49. if (value >= MaxValue)
  50. {
  51. MessageBox.Show("最小值不能超过最大值!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  52. minValue = ;
  53. }
  54. else
  55. {
  56. minValue = value;
  57. //drawBackImage();
  58. }
  59. }
  60.  
  61. }
  62.  
  63. /// <summary>
  64. /// 仪表盘上显示的最大值,默认123。
  65. /// </summary>
  66. private float maxValue = ;
  67.  
  68. /// <summary>
  69. /// 仪表盘上显示的最大值
  70. /// </summary>
  71. [Category("wyl")]
  72. [Description("仪表盘上显示的最大值")]
  73. public float MaxValue
  74. {
  75. get
  76. {
  77. return maxValue;
  78. }
  79. set
  80. {
  81. if (value <= MinValue)
  82. {
  83. MessageBox.Show("最大值不能低于最小值!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  84. maxValue = ;
  85. }
  86. else
  87. {
  88. maxValue = value;
  89. //drawBackImage();
  90. }
  91. }
  92. }
  93.  
  94. // <summary>
  95. /// 仪表盘变换的值,默认为0;
  96. /// </summary>
  97. private float changeValue = ;
  98.  
  99. /// <summary>
  100. /// 仪表盘变换的值
  101. /// </summary>
  102. public float ChangeValue
  103. {
  104. get
  105. {
  106. return changeValue;
  107. }
  108. set
  109. {
  110. changeValue = value;
  111. }
  112. }
  113.  
  114. /// <summary>
  115. /// 指针颜色
  116. /// </summary>
  117. private Color pinColor = Color.FromArgb(, , );
  118.  
  119. public Color PinColor
  120. {
  121. get
  122. {
  123. return pinColor;
  124. }
  125. set
  126. {
  127. pinColor = value;
  128. }
  129. }
  130.  
  131. public HalfDashboardUc()
  132. {
  133. InitializeComponent();
  134. //双缓存防止屏幕抖动
  135. this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.DoubleBuffer, true);
  136. this.SetStyle(ControlStyles.UserPaint, true);
  137. this.UpdateStyles();
  138. //设置背景颜色为透明
  139. this.BackColor = Color.Transparent;
  140. }
  141.  
  142. //private int uintfontsize = 40;
  143. /// <summary>
  144. /// 初始化仪表盘画布
  145. /// </summary>
  146. private void InitialCanvas()
  147. {
  148. //对比控件的长高,以最小值为仪表盘的半径
  149. if (this.Width > * this.Height)
  150. {
  151. diameter = * this.Height - ;
  152. }
  153. else
  154. {
  155. diameter = this.Width - ;
  156. }
  157. multiple = (float)diameter / maxSize;//计算仪表盘放大倍数
  158. //如果半径大于仪表盘的最大值,则设定放大倍数为默认值
  159. if (multiple > )
  160. {
  161. multiple = ;
  162. diameter = maxSize;
  163. }
  164. intervalValue = (int)((MaxValue - minValue) / );//计算每个间隔之间的值
  165. }
  166.  
  167. /// <summary>
  168. /// 画底图
  169. /// </summary>
  170. private void drawBackImage()
  171. {
  172.  
  173. Bitmap bit = new Bitmap(this.Width, this.Height);
  174. Graphics gp = Graphics.FromImage(bit);
  175. gp.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
  176. float radius = diameter / ;//半径
  177. float cerX = this.Width / ;
  178. float cerY = this.Height / + radius / - * multiple;
  179. //float cerY = this.Height - 20 ;
  180. gp.TranslateTransform(cerX, cerY);//以中心点为画布的起始点
  181. //gp.DrawPie(new Pen(new SolidBrush(Color.FromArgb(19,20,25)),3), -radius, -radius, diameter, diameter, 175, 190);
  182. gp.DrawArc(new Pen(new SolidBrush(Color.FromArgb(, , )), ), -radius, -radius, diameter, diameter, , );
  183. float x1 = (float)((radius) * Math.Cos( * Math.PI / ));
  184. float y1 = (float)((radius) * Math.Sin( * Math.PI / ));
  185. float x2 = (float)((radius) * Math.Cos( * Math.PI / ));
  186. float y2 = (float)((radius) * Math.Sin( * Math.PI / ));
  187. gp.DrawLine(new Pen(new SolidBrush(Color.FromArgb(, , )), ), x1, y1, x2, y2);
  188.  
  189. //gp.DrawEllipse(new Pen(Brushes.Red), -5, -5, 10, 10);
  190. float startRad = ;//起始角度
  191. float sweepShot = ;//旋转角度
  192. //gp.DrawLine(new Pen(Brushes.Red), -radius, 0, -(radius - 10), 0);
  193. for (int i = ; i <= ; i++)
  194. {
  195. double rad = (sweepShot + startRad) * Math.PI / ;
  196. if (i % == )
  197. {
  198. float px1 = (float)((radius - ) * Math.Cos(rad));
  199. float py1 = (float)((radius - ) * Math.Sin(rad));
  200.  
  201. float px2 = (float)((radius - ) * Math.Cos(rad));
  202. float py2 = (float)((radius - ) * Math.Sin(rad));
  203. gp.DrawLine(new Pen(new SolidBrush(Color.FromArgb(, , )), ), px1, py1, px2, py2);
  204.  
  205. }
  206. else
  207. {
  208.  
  209. float px1 = (float)((radius - ) * Math.Cos(rad));
  210. float py1 = (float)((radius - ) * Math.Sin(rad));
  211.  
  212. float px2 = (float)((radius - ) * Math.Cos(rad));
  213. float py2 = (float)((radius - ) * Math.Sin(rad));
  214. gp.DrawLine(new Pen(new SolidBrush(Color.FromArgb(, , )), ), px1, py1, px2, py2);
  215. }
  216. sweepShot += ;
  217. }
  218. //刻度字体
  219. Font scaleFont = new Font("宋体", , FontStyle.Bold);
  220. startRad = ;//起始角度
  221. sweepShot = ;//旋转角度
  222. Color c1 = Color.FromArgb(, , );
  223. for (int i = ; i < ; i++)
  224. {
  225. int tempValue = i * intervalValue;
  226. SizeF tempSf = gp.MeasureString(tempValue.ToString(), scaleFont);
  227. //计算角度值
  228. double rad = (sweepShot + startRad) * Math.PI / ;
  229. float px = (float)((radius - ) * Math.Cos(rad));
  230. float py = (float)((radius - ) * Math.Sin(rad));
  231. if (sweepShot == )
  232. {
  233. gp.DrawString(tempValue.ToString(), scaleFont, Brushes.Wheat, px - tempSf.Width / , py);
  234. }
  235. else if (sweepShot == )
  236. {
  237. gp.DrawString(tempValue.ToString(), scaleFont, new SolidBrush(c1), px - tempSf.Width + * multiple, py - tempSf.Height / + * multiple);
  238. }
  239. else if (sweepShot == )
  240. {
  241. gp.DrawString(tempValue.ToString(), scaleFont, new SolidBrush(c1), px - tempSf.Width, py - tempSf.Height / + * multiple);
  242. }
  243. else if (sweepShot == )
  244. {
  245. gp.DrawString(tempValue.ToString(), scaleFont, new SolidBrush(c1), px - tempSf.Width, py - tempSf.Height / );
  246.  
  247. }
  248. //else if (sweepShot == 120)
  249. //{
  250. // gp.DrawString(tempValue.ToString(), scaleFont, new SolidBrush(c1), px - tempSf.Width, py - tempSf.Height / 2);
  251. //}
  252. sweepShot += ;
  253. }
  254. startRad = ;//起始角度
  255. sweepShot = ;//旋转角度
  256. for (int i = ; i < ; i++)
  257. {
  258. int tempValue = -i * intervalValue;
  259. SizeF tempSf = gp.MeasureString(tempValue.ToString(), scaleFont);
  260. //计算角度值
  261. double rad = (sweepShot + startRad) * Math.PI / ;
  262. float px = (float)((radius - * multiple) * Math.Cos(rad));
  263. float py = (float)((radius - * multiple) * Math.Sin(rad));
  264. if (sweepShot == -)
  265. {
  266. gp.DrawString(tempValue.ToString(), scaleFont, Brushes.Red, px, py + tempSf.Height / );
  267. }
  268. else if (sweepShot == -)
  269. {
  270. gp.DrawString(tempValue.ToString(), scaleFont, Brushes.Red, px + tempSf.Width / - * multiple, py + tempSf.Height / - * multiple);
  271. }
  272. else if (sweepShot == -)
  273. {
  274. gp.DrawString(tempValue.ToString(), scaleFont, Brushes.Red, px + tempSf.Width/ , py - tempSf.Height / );
  275.  
  276. }
  277.  
  278. sweepShot -= ;
  279. }
  280.  
  281. gp.Dispose();
  282. this.BackgroundImage = bit;
  283. }
  284.  
  285. /// <summary>
  286. /// 画图
  287. /// </summary>
  288. /// <param name="g"></param>
  289. private void DrawPin(Graphics g)
  290. {
  291. Bitmap bit = new Bitmap(this.Width, this.Height);
  292. Graphics gp = Graphics.FromImage(bit);
  293. gp.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
  294. float radius = diameter / ;//半径
  295. float startRad = ;//起始角度
  296. float sweepShot = (float)(ChangeValue / MaxValue * );//旋转角度
  297. float cerX = this.Width / ;
  298. float cerY = this.Height / + radius / - * multiple;
  299. gp.TranslateTransform(cerX, cerY);//以中心点为画布的起始点
  300. //gp.DrawEllipse(new Pen(PinColor, 1), -5, -5, 10, 10);//画中心圆圈
  301. double rad = (sweepShot + startRad) * Math.PI / ;//计算角度
  302. float px = (float)((radius - ) * Math.Cos(rad));
  303. float py = (float)((radius - ) * Math.Sin(rad));
  304. PointF[] pf = new PointF[] { new PointF(, -radius + ), new PointF(-, ), new PointF(, ) };
  305. gp.RotateTransform(sweepShot);
  306. //PointF[] pf = new PointF[] { new PointF(px, py), new PointF(-4, 0), new PointF(4, 0) };
  307. gp.FillPolygon(new SolidBrush(PinColor), pf);
  308.  
  309. //gp.DrawLine(new Pen(new SolidBrush(PinColor), 3f), 0, 0, px, py);
  310.  
  311. g.DrawImage(bit, , );
  312. gp.Dispose();
  313. }
  314.  
  315. private void HalfDashboardUc_Load(object sender, EventArgs e)
  316. {
  317. InitialCanvas();
  318. drawBackImage();
  319. }
  320.  
  321. private void HalfDashboardUc_Paint(object sender, PaintEventArgs e)
  322. {
  323. DrawPin(e.Graphics);
  324. }
  325.  
  326. private void HalfDashboardUc_Resize(object sender, EventArgs e)
  327. {
  328. InitialCanvas();
  329. drawBackImage();
  330. }
  331. }

效果实现如下:

金属仪表盘下载地址 https://pan.baidu.com/s/1xANmSkQYnLGzUJ_X8Dbg0w   提取码:fi96

C# GDI绘制仪表盘(纯代码实现)的更多相关文章

  1. GDI绘制时钟效果,与系统时间保持同步,基于Winform

    2018年工作之余,想起来捡起GDI方面的技术,特意在RichCodeBox项目中做了两个示例程序,其中一个就是时钟效果,纯C#开发.这个CSharpQuartz是今天上午抽出一些时间,编写的,算是偷 ...

  2. 通过GDI+绘制 验证码

    只为了记录下自己的学习历程,方便日后查看 现在开始言归正传,以下为其完整代码附上 using System; using System.Collections.Generic; using Syste ...

  3. C#利用GDI+绘制旋转文字等效果

    C#中利用GDI+绘制旋转文本的文字,网上有很多资料,基本都使用矩阵旋转的方式实现.但基本都只提及按点旋转,若要实现在矩形范围内旋转文本,资料较少.经过琢磨,可以将矩形内旋转转化为按点旋转,不过需要经 ...

  4. C# 使用GDI+绘制漂亮的MenuStrip和ContextMenuStrip皮肤

    通过上面的效果截图可以看到,重绘后的MenuStrip和ContextMenuStrip可以添加自己的LOGO信息,实现了类似OFFICE2007的菜单显示效果. .NET对菜单控件的绘制提供了一个抽 ...

  5. MFC 用gdi绘制填充多边形区域

    MFC 用gdi绘制填充多边形区域 这里的代码是实现一个三角形的绘制,并用刷子填充颜色 在OnPaint()函数里面 运用的是给定的三角形的三个点,很多个点可以绘制多边形 CBrush br(RGB( ...

  6. 『备注』GDI+ 绘制文本有锯齿,透明背景文本绘制

    背景: GDI+ 绘制文本 时,如果 背景是透明的 —— 则会出现 锯齿. //其实,我不用这三个 属性 好多年了 //而且,这三个属性 在关键时刻还有可能 帮倒忙 //关键是:这三个属性,鸟用都没有 ...

  7. C#GDI+ 绘制线段(实线或虚线)、矩形、字符串、圆、椭圆

    C#GDI+ 绘制线段(实线或虚线).矩形.字符串.圆.椭圆 绘制基本线条和图形 比较简单,直接看代码. Graphics graphics = e.Graphics; //绘制实线 )) { pen ...

  8. Qt自定义控件之仪表盘2--QPaint绘制仪表盘

    0.前言 前面一篇文章写道了仪表盘的特点,实现了一个贴图的仪表盘,属于低配版本的仪表盘.    主要是有任何改动时候就需要重新设计图片,不能适配不同控件大小,即使让它自由拉伸,但仪表盘放大缩小时候显示 ...

  9. Qt5绘制仪表盘dashboard

    说明 本文演示Qt版本: Qt5.14. 本文将使用QPainter一步一步绘制仪表盘:刻度.指针.刻度值 注意: 绘制顺序,如果先绘制,则后来绘制的将会覆盖住先前绘制的. 如果需要绘制半透明, 请设 ...

随机推荐

  1. My97DatePicker 日历控件

    My97DatePicker 是一款非常强大的日历控件,使用也非常简单,也能修改源码,牛逼我就不吹了,自己用用看 使用 1.引入 <script language="javascrip ...

  2. jsp页面遍历List<Array>与Map

    数据结构下如图所示,之前的前辈遍历方法如下,代码直接抛异常哈, <c:if test="${!empty data1}"> <c:forEach items=&q ...

  3. 从文件中读取字符-多次调用read characters from file multiple calls

    [抄题]: 接口:int read4(char * buf)一次从文件中读取 4 个字符.返回值是实际读取的字符数. 例如,如果文件中只剩下 3 个字符,则返回 3.通过使用read4 接口,实现从文 ...

  4. css3阴影效果

    http://blog.csdn.net/freshlover/article/details/7610269

  5. 为什么大神的UI设计那么高级?答案尽在此文…

    对于每个网页设计师而言,在设计过程中总会碰到需要作出设计决策的时候.也许你的公司并没有全职设计师,而需求上则要求设计出全新的UI:又或者你正在制作一个你自己的个人项目,而你希望它比 Bootstrap ...

  6. 设置zookeeper为systemctl守护进程

    ==目的== 想把zookeeper.hadoop.hbase.storm等大数据组件 设置为开机启动,并且进程挂掉之后,可以自动重启,以减少运维压力. ==service文件== 路径:/usr/l ...

  7. 关闭文件流--fclose,

    头文件:#include<stdio.h> 函数原型:int fclose(FILE *fp) 参数说明:fp将被关闭的文件指针 返回值:成功返回0,失败返回EOF宏.

  8. Oracle sql的基本优化写法和思路。

    首先简单介绍下常规的sql优化的方式: 1.肯定有人说建索引啊. 2.数据量实在太大,建分区啊. 3.其实基于目前公司的业务还有一种办法那就是向上聚集表.根据查询业务,专门抽取上来一张表,直接做到se ...

  9. 使用delphi 开发多层应用(二十四)KbmMW 的消息方式和创建WIB节点

    KbmMW 中支持基于UDP的消息广播,也支持TCP/IP hub/spoke 方式,还有 基于UDP或者TCP/IP 的点对点的消息传输. 1.基于UDP的消息广播

  10. spring-data-jpa+hibernate 各种缓存的配置演示

    本文所有测试用代码在https://github.com/wwlleo0730/restjplat 的分支addDB上 目前在使用spring-data-jpa和hibernate4的时候,对于缓存关 ...