• (六十四)c#Winform自定义控件-温度计(工业)-HZHControls


    官网

    http://www.hzhcontrols.com

    前提

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

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

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

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

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

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

    NuGet

    Install-Package HZH_Controls

    目录

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

    用处及效果

    准备工作

    依然用GID+画的,不懂请自行百度

    开始

    添加一个类UCThermometer,继承UserControl

    添加一个枚举,来决定显示的温度单位

     1  public enum TemperatureUnit
     2     {
     3         /// <summary>
     4         /// 不显示
     5         /// </summary>
     6         None,
     7         /// <summary>
     8         /// 摄氏度
     9         /// </summary>
    10         C,
    11         /// <summary>
    12         /// 华氏度
    13         /// </summary>
    14         F,
    15         /// <summary>
    16         /// 开氏度
    17         /// </summary>
    18         K,
    19         /// <summary>
    20         /// 兰氏度
    21         /// </summary>
    22         R,
    23         /// <summary>
    24         /// 列氏度
    25         /// </summary>
    26         Re
    27     }

    添加一些属性

      1 /// <summary>
      2         /// The glass tube color
      3         /// </summary>
      4         private Color glassTubeColor = Color.FromArgb(211, 211, 211);
      5 
      6         /// <summary>
      7         /// Gets or sets the color of the glass tube.
      8         /// </summary>
      9         /// <value>The color of the glass tube.</value>
     10         [Description("玻璃管颜色"), Category("自定义")]
     11         public Color GlassTubeColor
     12         {
     13             get { return glassTubeColor; }
     14             set
     15             {
     16                 glassTubeColor = value;
     17                 Refresh();
     18             }
     19         }
     20 
     21         /// <summary>
     22         /// The mercury color
     23         /// </summary>
     24         private Color mercuryColor = Color.FromArgb(255, 77, 59);
     25 
     26         /// <summary>
     27         /// Gets or sets the color of the mercury.
     28         /// </summary>
     29         /// <value>The color of the mercury.</value>
     30         [Description("水印颜色"), Category("自定义")]
     31         public Color MercuryColor
     32         {
     33             get { return mercuryColor; }
     34             set
     35             {
     36                 mercuryColor = value;
     37                 Refresh();
     38             }
     39         }
     40 
     41         /// <summary>
     42         /// The minimum value
     43         /// </summary>
     44         private decimal minValue = 0;
     45         /// <summary>
     46         /// 左侧刻度最小值
     47         /// </summary>
     48         /// <value>The minimum value.</value>
     49         [Description("左侧刻度最小值"), Category("自定义")]
     50         public decimal MinValue
     51         {
     52             get { return minValue; }
     53             set
     54             {
     55                 minValue = value;
     56                 Refresh();
     57             }
     58         }
     59 
     60         /// <summary>
     61         /// The maximum value
     62         /// </summary>
     63         private decimal maxValue = 100;
     64         /// <summary>
     65         /// 左侧刻度最大值
     66         /// </summary>
     67         /// <value>The maximum value.</value>
     68         [Description("左侧刻度最大值"), Category("自定义")]
     69         public decimal MaxValue
     70         {
     71             get { return maxValue; }
     72             set
     73             {
     74                 maxValue = value;
     75                 Refresh();
     76             }
     77         }
     78 
     79         /// <summary>
     80         /// The m value
     81         /// </summary>
     82         private decimal m_value = 10;
     83         /// <summary>
     84         /// 左侧刻度值
     85         /// </summary>
     86         /// <value>The value.</value>
     87         [Description("左侧刻度值"), Category("自定义")]
     88         public decimal Value
     89         {
     90             get { return m_value; }
     91             set
     92             {
     93                 m_value = value;
     94                 Refresh();
     95             }
     96         }
     97 
     98         /// <summary>
     99         /// The split count
    100         /// </summary>
    101         private int splitCount = 0;
    102         /// <summary>
    103         /// 刻度分隔份数
    104         /// </summary>
    105         /// <value>The split count.</value>
    106         [Description("刻度分隔份数"), Category("自定义")]
    107         public int SplitCount
    108         {
    109             get { return splitCount; }
    110             set
    111             {
    112                 if (value <= 0)
    113                     return;
    114                 splitCount = value;
    115                 Refresh();
    116             }
    117         }
    118 
    119         /// <summary>
    120         /// 获取或设置控件显示的文字的字体。
    121         /// </summary>
    122         /// <value>The font.</value>
    123         /// <PermissionSet>
    124         ///   <IPermission class="System.Security.Permissions.EnvironmentPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
    125         ///   <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
    126         ///   <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="UnmanagedCode, ControlEvidence" />
    127         ///   <IPermission class="System.Diagnostics.PerformanceCounterPermission, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
    128         /// </PermissionSet>
    129         [Description("获取或设置控件显示的文字的字体"), Category("自定义")]
    130         public override Font Font
    131         {
    132             get
    133             {
    134                 return base.Font;
    135             }
    136             set
    137             {
    138                 base.Font = value;
    139                 Refresh();
    140             }
    141         }
    142 
    143         /// <summary>
    144         /// 获取或设置控件的前景色。
    145         /// </summary>
    146         /// <value>The color of the fore.</value>
    147         /// <PermissionSet>
    148         ///   <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
    149         /// </PermissionSet>
    150         [Description("获取或设置控件的文字及刻度颜色"), Category("自定义")]
    151         public override System.Drawing.Color ForeColor
    152         {
    153             get
    154             {
    155                 return base.ForeColor;
    156             }
    157             set
    158             {
    159                 base.ForeColor = value;
    160                 Refresh();
    161             }
    162         }
    163 
    164         /// <summary>
    165         /// The left temperature unit
    166         /// </summary>
    167         private TemperatureUnit leftTemperatureUnit = TemperatureUnit.C;
    168         /// <summary>
    169         /// 左侧刻度单位,不可为none
    170         /// </summary>
    171         /// <value>The left temperature unit.</value>
    172         [Description("左侧刻度单位,不可为none"), Category("自定义")]
    173         public TemperatureUnit LeftTemperatureUnit
    174         {
    175             get { return leftTemperatureUnit; }
    176             set
    177             {
    178                 if (value == TemperatureUnit.None)
    179                     return;
    180                 leftTemperatureUnit = value;
    181                 Refresh();
    182             }
    183         }
    184 
    185         /// <summary>
    186         /// The right temperature unit
    187         /// </summary>
    188         private TemperatureUnit rightTemperatureUnit = TemperatureUnit.C;
    189         /// <summary>
    190         /// 右侧刻度单位,当为none时,不显示
    191         /// </summary>
    192         /// <value>The right temperature unit.</value>
    193         [Description("右侧刻度单位,当为none时,不显示"), Category("自定义")]
    194         public TemperatureUnit RightTemperatureUnit
    195         {
    196             get { return rightTemperatureUnit; }
    197             set
    198             {
    199                 rightTemperatureUnit = value;
    200                 Refresh();
    201             }
    202         }
    203 
    204         /// <summary>
    205         /// The m rect working
    206         /// </summary>
    207         Rectangle m_rectWorking;
    208         /// <summary>
    209         /// The m rect left
    210         /// </summary>
    211         Rectangle m_rectLeft;
    212         /// <summary>
    213         /// The m rect right
    214         /// </summary>
    215         Rectangle m_rectRight;

    改变大小时,设定画图区域

    1  void UCThermometer_SizeChanged(object sender, EventArgs e)
    2         {
    3             m_rectWorking = new Rectangle(this.Width / 2 - this.Width / 8, this.Width / 4, this.Width / 4, this.Height - this.Width / 2);
    4             m_rectLeft = new Rectangle(0, m_rectWorking.Top + m_rectWorking.Width / 2, (this.Width - this.Width / 4) / 2 - 2, m_rectWorking.Height - m_rectWorking.Width * 2);
    5             m_rectRight = new Rectangle(this.Width - (this.Width - this.Width / 4) / 2 + 2, m_rectWorking.Top + m_rectWorking.Width / 2, (this.Width - this.Width / 4) / 2 - 2, m_rectWorking.Height - m_rectWorking.Width * 2);
    6         }

    重绘

     1  protected override void OnPaint(PaintEventArgs e)
     2         {
     3             base.OnPaint(e);
     4             var g = e.Graphics;
     5             g.SetGDIHigh();
     6 
     7             //玻璃管管
     8             GraphicsPath path = new GraphicsPath();
     9             path.AddLine(m_rectWorking.Left, m_rectWorking.Bottom, m_rectWorking.Left, m_rectWorking.Top + m_rectWorking.Width / 2);
    10             path.AddArc(new Rectangle(m_rectWorking.Left, m_rectWorking.Top, m_rectWorking.Width, m_rectWorking.Width), 180, 180);
    11             path.AddLine(m_rectWorking.Right, m_rectWorking.Top + m_rectWorking.Width / 2, m_rectWorking.Right, m_rectWorking.Bottom);
    12             path.CloseAllFigures();
    13             g.FillPath(new SolidBrush(glassTubeColor), path);
    14 
    15             //底部
    16             var rectDi = new Rectangle(this.Width / 2 - m_rectWorking.Width, m_rectWorking.Bottom - m_rectWorking.Width - 2, m_rectWorking.Width * 2, m_rectWorking.Width * 2);
    17             g.FillEllipse(new SolidBrush(glassTubeColor), rectDi);
    18             g.FillEllipse(new SolidBrush(mercuryColor), new Rectangle(rectDi.Left + 4, rectDi.Top + 4, rectDi.Width - 8, rectDi.Height - 8));
    19 
    20             //刻度
    21             decimal decSplit = (maxValue - minValue) / splitCount;
    22             decimal decSplitHeight = m_rectLeft.Height / splitCount;
    23             for (int i = 0; i <= splitCount; i++)
    24             {
    25                 g.DrawLine(new Pen(new SolidBrush(ForeColor), 1), new PointF(m_rectLeft.Left + 2, (float)(m_rectLeft.Bottom - decSplitHeight * i)), new PointF(m_rectLeft.Right, (float)(m_rectLeft.Bottom - decSplitHeight * i)));
    26 
    27                 var valueLeft = (minValue + decSplit * i).ToString("0.##");
    28                 var sizeLeft = g.MeasureString(valueLeft, Font);
    29                 g.DrawString(valueLeft, Font, new SolidBrush(ForeColor), new PointF(m_rectLeft.Left, m_rectLeft.Bottom - (float)decSplitHeight * i - sizeLeft.Height - 1));
    30 
    31                 if (rightTemperatureUnit != TemperatureUnit.None)
    32                 {
    33                     g.DrawLine(new Pen(new SolidBrush(Color.Black), 1), new PointF(m_rectRight.Left + 2, (float)(m_rectRight.Bottom - decSplitHeight * i)), new PointF(m_rectRight.Right, (float)(m_rectRight.Bottom - decSplitHeight * i)));
    34                     var valueRight = GetRightValue(minValue + decSplit * i).ToString("0.##");
    35                     var sizeRight = g.MeasureString(valueRight, Font);
    36                     g.DrawString(valueRight, Font, new SolidBrush(ForeColor), new PointF(m_rectRight.Right - sizeRight.Width - 1, m_rectRight.Bottom - (float)decSplitHeight * i - sizeRight.Height - 1));
    37                 }
    38                 if (i != splitCount)
    39                 {
    40                     if (decSplitHeight > 40)
    41                     {
    42                         var decSp1 = decSplitHeight / 10;
    43                         for (int j = 1; j < 10; j++)
    44                         {
    45                             if (j == 5)
    46                             {
    47                                 g.DrawLine(new Pen(new SolidBrush(ForeColor), 1), new PointF(m_rectLeft.Right - 10, (m_rectLeft.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))), new PointF(m_rectLeft.Right, (m_rectLeft.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))));
    48                                 if (rightTemperatureUnit != TemperatureUnit.None)
    49                                 {
    50                                     g.DrawLine(new Pen(new SolidBrush(ForeColor), 1), new PointF(m_rectRight.Left + 10, (m_rectRight.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))), new PointF(m_rectRight.Left, (m_rectRight.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))));
    51                                 }
    52                             }
    53                             else
    54                             {
    55                                 g.DrawLine(new Pen(new SolidBrush(ForeColor), 1), new PointF(m_rectLeft.Right - 5, (m_rectLeft.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))), new PointF(m_rectLeft.Right, (m_rectLeft.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))));
    56                                 if (rightTemperatureUnit != TemperatureUnit.None)
    57                                 {
    58                                     g.DrawLine(new Pen(new SolidBrush(ForeColor), 1), new PointF(m_rectRight.Left + 5, (m_rectRight.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))), new PointF(m_rectRight.Left, (m_rectRight.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))));
    59                                 }
    60                             }
    61                         }
    62                     }
    63                     else if (decSplitHeight > 10)
    64                     {
    65                         g.DrawLine(new Pen(new SolidBrush(ForeColor), 1), new PointF(m_rectLeft.Right - 5, (m_rectLeft.Bottom - (float)decSplitHeight * i - (float)decSplitHeight / 2)), new PointF(m_rectLeft.Right, (m_rectLeft.Bottom - (float)decSplitHeight * i - (float)decSplitHeight / 2)));
    66                         if (rightTemperatureUnit != TemperatureUnit.None)
    67                         {
    68                             g.DrawLine(new Pen(new SolidBrush(ForeColor), 1), new PointF(m_rectRight.Left + 5, (m_rectRight.Bottom - (float)decSplitHeight * i - (float)decSplitHeight / 2)), new PointF(m_rectRight.Left, (m_rectRight.Bottom - (float)decSplitHeight * i - (float)decSplitHeight / 2)));
    69                         }
    70                     }
    71                 }
    72             }
    73             //单位
    74             string strLeftUnit = GetUnitChar(leftTemperatureUnit);
    75             g.DrawString(strLeftUnit, Font, new SolidBrush(ForeColor), new PointF(m_rectLeft.Left + 2, 2));
    76             if (rightTemperatureUnit != TemperatureUnit.None)
    77             {
    78                 string strRightUnit = GetUnitChar(rightTemperatureUnit);
    79                 var rightSize = g.MeasureString(strRightUnit, Font);
    80                 g.DrawString(strRightUnit, Font, new SolidBrush(ForeColor), new PointF(m_rectRight.Right - 2 - rightSize.Width, 2));
    81             }
    82             //
    83             float fltHeightValue = (float)(Value / (maxValue - minValue) * m_rectLeft.Height);
    84             RectangleF rectValue = new RectangleF(m_rectWorking.Left + 4, m_rectLeft.Top + (m_rectLeft.Height - fltHeightValue), m_rectWorking.Width - 8, fltHeightValue + (m_rectWorking.Height - m_rectWorking.Width / 2 - m_rectLeft.Height));
    85             g.FillRectangle(new SolidBrush(mercuryColor), rectValue);
    86 
    87 
    88             var sizeValue = g.MeasureString(m_value.ToString("0.##"), Font);
    89             g.DrawString(m_value.ToString("0.##"), Font, new SolidBrush(Color.White), new PointF(rectDi.Left + (rectDi.Width - sizeValue.Width) / 2, rectDi.Top + (rectDi.Height - sizeValue.Height) / 2 + 1));
    90         }

    辅助函数

     1 private string GetUnitChar(TemperatureUnit unit)
     2         {
     3             string strUnit = "";
     4             switch (unit)
     5             {
     6                 case TemperatureUnit.C:
     7                     strUnit = "";
     8                     break;
     9                 case TemperatureUnit.F:
    10                     strUnit = "";
    11                     break;
    12                 case TemperatureUnit.K:
    13                     strUnit = "K";
    14                     break;
    15                 case TemperatureUnit.R:
    16                     strUnit = "°R";
    17                     break;
    18                 case TemperatureUnit.Re:
    19                     strUnit = "°Re";
    20                     break;
    21             }
    22             return strUnit;
    23         }
    24 
    25         private decimal GetRightValue(decimal decValue)
    26         {
    27             //先将左侧的换算为摄氏度
    28             var dec = decValue;
    29             switch (leftTemperatureUnit)
    30             {
    31                 case TemperatureUnit.F:
    32                     dec = (decValue - 32) / (9M / 5M);
    33                     break;
    34                 case TemperatureUnit.K:
    35                     dec = decValue - 273;
    36                     break;
    37                 case TemperatureUnit.R:
    38                     dec = decValue / (5M / 9M) - 273.15M;
    39                     break;
    40                 case TemperatureUnit.Re:
    41                     dec = decValue / 1.25M;
    42                     break;
    43                 default:
    44                     break;
    45             }
    46 
    47             switch (rightTemperatureUnit)
    48             {
    49                 case TemperatureUnit.C:
    50                     return dec;
    51                 case TemperatureUnit.F:
    52                     return 9M / 5M * dec + 32;
    53                 case TemperatureUnit.K:
    54                     return dec + 273;
    55                 case TemperatureUnit.R:
    56                     return (dec + 273.15M) * (5M / 9M);
    57                 case TemperatureUnit.Re:
    58                     return dec * 1.25M;
    59             }
    60             return decValue;
    61         }

    完整代码

      1 // ***********************************************************************
      2 // Assembly         : HZH_Controls
      3 // Created          : 2019-09-10
      4 //
      5 // ***********************************************************************
      6 // <copyright file="UCThermometer.cs">
      7 //     Copyright by Huang Zhenghui(黄正辉) All, QQ group:568015492 QQ:623128629 Email:623128629@qq.com
      8 // </copyright>
      9 //
     10 // Blog: https://www.cnblogs.com/bfyx
     11 // GitHub:https://github.com/kwwwvagaa/NetWinformControl
     12 // gitee:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
     13 //
     14 // If you use this code, please keep this note.
     15 // ***********************************************************************
     16 using System;
     17 using System.Collections.Generic;
     18 using System.Linq;
     19 using System.Text;
     20 using System.Windows.Forms;
     21 using System.Drawing;
     22 using System.Drawing.Drawing2D;
     23 using System.ComponentModel;
     24 
     25 namespace HZH_Controls.Controls
     26 {
     27     /// <summary>
     28     /// Class UCThermometer.
     29     /// Implements the <see cref="System.Windows.Forms.UserControl" />
     30     /// </summary>
     31     /// <seealso cref="System.Windows.Forms.UserControl" />
     32     public class UCThermometer : UserControl
     33     {
     34         /// <summary>
     35         /// The glass tube color
     36         /// </summary>
     37         private Color glassTubeColor = Color.FromArgb(211, 211, 211);
     38 
     39         /// <summary>
     40         /// Gets or sets the color of the glass tube.
     41         /// </summary>
     42         /// <value>The color of the glass tube.</value>
     43         [Description("玻璃管颜色"), Category("自定义")]
     44         public Color GlassTubeColor
     45         {
     46             get { return glassTubeColor; }
     47             set
     48             {
     49                 glassTubeColor = value;
     50                 Refresh();
     51             }
     52         }
     53 
     54         /// <summary>
     55         /// The mercury color
     56         /// </summary>
     57         private Color mercuryColor = Color.FromArgb(255, 77, 59);
     58 
     59         /// <summary>
     60         /// Gets or sets the color of the mercury.
     61         /// </summary>
     62         /// <value>The color of the mercury.</value>
     63         [Description("水印颜色"), Category("自定义")]
     64         public Color MercuryColor
     65         {
     66             get { return mercuryColor; }
     67             set
     68             {
     69                 mercuryColor = value;
     70                 Refresh();
     71             }
     72         }
     73 
     74         /// <summary>
     75         /// The minimum value
     76         /// </summary>
     77         private decimal minValue = 0;
     78         /// <summary>
     79         /// 左侧刻度最小值
     80         /// </summary>
     81         /// <value>The minimum value.</value>
     82         [Description("左侧刻度最小值"), Category("自定义")]
     83         public decimal MinValue
     84         {
     85             get { return minValue; }
     86             set
     87             {
     88                 minValue = value;
     89                 Refresh();
     90             }
     91         }
     92 
     93         /// <summary>
     94         /// The maximum value
     95         /// </summary>
     96         private decimal maxValue = 100;
     97         /// <summary>
     98         /// 左侧刻度最大值
     99         /// </summary>
    100         /// <value>The maximum value.</value>
    101         [Description("左侧刻度最大值"), Category("自定义")]
    102         public decimal MaxValue
    103         {
    104             get { return maxValue; }
    105             set
    106             {
    107                 maxValue = value;
    108                 Refresh();
    109             }
    110         }
    111 
    112         /// <summary>
    113         /// The m value
    114         /// </summary>
    115         private decimal m_value = 10;
    116         /// <summary>
    117         /// 左侧刻度值
    118         /// </summary>
    119         /// <value>The value.</value>
    120         [Description("左侧刻度值"), Category("自定义")]
    121         public decimal Value
    122         {
    123             get { return m_value; }
    124             set
    125             {
    126                 m_value = value;
    127                 Refresh();
    128             }
    129         }
    130 
    131         /// <summary>
    132         /// The split count
    133         /// </summary>
    134         private int splitCount = 0;
    135         /// <summary>
    136         /// 刻度分隔份数
    137         /// </summary>
    138         /// <value>The split count.</value>
    139         [Description("刻度分隔份数"), Category("自定义")]
    140         public int SplitCount
    141         {
    142             get { return splitCount; }
    143             set
    144             {
    145                 if (value <= 0)
    146                     return;
    147                 splitCount = value;
    148                 Refresh();
    149             }
    150         }
    151 
    152         /// <summary>
    153         /// 获取或设置控件显示的文字的字体。
    154         /// </summary>
    155         /// <value>The font.</value>
    156         /// <PermissionSet>
    157         ///   <IPermission class="System.Security.Permissions.EnvironmentPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
    158         ///   <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
    159         ///   <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="UnmanagedCode, ControlEvidence" />
    160         ///   <IPermission class="System.Diagnostics.PerformanceCounterPermission, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
    161         /// </PermissionSet>
    162         [Description("获取或设置控件显示的文字的字体"), Category("自定义")]
    163         public override Font Font
    164         {
    165             get
    166             {
    167                 return base.Font;
    168             }
    169             set
    170             {
    171                 base.Font = value;
    172                 Refresh();
    173             }
    174         }
    175 
    176         /// <summary>
    177         /// 获取或设置控件的前景色。
    178         /// </summary>
    179         /// <value>The color of the fore.</value>
    180         /// <PermissionSet>
    181         ///   <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
    182         /// </PermissionSet>
    183         [Description("获取或设置控件的文字及刻度颜色"), Category("自定义")]
    184         public override System.Drawing.Color ForeColor
    185         {
    186             get
    187             {
    188                 return base.ForeColor;
    189             }
    190             set
    191             {
    192                 base.ForeColor = value;
    193                 Refresh();
    194             }
    195         }
    196 
    197         /// <summary>
    198         /// The left temperature unit
    199         /// </summary>
    200         private TemperatureUnit leftTemperatureUnit = TemperatureUnit.C;
    201         /// <summary>
    202         /// 左侧刻度单位,不可为none
    203         /// </summary>
    204         /// <value>The left temperature unit.</value>
    205         [Description("左侧刻度单位,不可为none"), Category("自定义")]
    206         public TemperatureUnit LeftTemperatureUnit
    207         {
    208             get { return leftTemperatureUnit; }
    209             set
    210             {
    211                 if (value == TemperatureUnit.None)
    212                     return;
    213                 leftTemperatureUnit = value;
    214                 Refresh();
    215             }
    216         }
    217 
    218         /// <summary>
    219         /// The right temperature unit
    220         /// </summary>
    221         private TemperatureUnit rightTemperatureUnit = TemperatureUnit.C;
    222         /// <summary>
    223         /// 右侧刻度单位,当为none时,不显示
    224         /// </summary>
    225         /// <value>The right temperature unit.</value>
    226         [Description("右侧刻度单位,当为none时,不显示"), Category("自定义")]
    227         public TemperatureUnit RightTemperatureUnit
    228         {
    229             get { return rightTemperatureUnit; }
    230             set
    231             {
    232                 rightTemperatureUnit = value;
    233                 Refresh();
    234             }
    235         }
    236 
    237         /// <summary>
    238         /// The m rect working
    239         /// </summary>
    240         Rectangle m_rectWorking;
    241         /// <summary>
    242         /// The m rect left
    243         /// </summary>
    244         Rectangle m_rectLeft;
    245         /// <summary>
    246         /// The m rect right
    247         /// </summary>
    248         Rectangle m_rectRight;
    249         /// <summary>
    250         /// Initializes a new instance of the <see cref="UCThermometer"/> class.
    251         /// </summary>
    252         public UCThermometer()
    253         {
    254             this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
    255             this.SetStyle(ControlStyles.DoubleBuffer, true);
    256             this.SetStyle(ControlStyles.ResizeRedraw, true);
    257             this.SetStyle(ControlStyles.Selectable, true);
    258             this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
    259             this.SetStyle(ControlStyles.UserPaint, true);
    260             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
    261             this.SizeChanged += UCThermometer_SizeChanged;
    262             this.Size = new Size(70, 200);
    263         }
    264 
    265         /// <summary>
    266         /// Handles the SizeChanged event of the UCThermometer control.
    267         /// </summary>
    268         /// <param name="sender">The source of the event.</param>
    269         /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
    270         void UCThermometer_SizeChanged(object sender, EventArgs e)
    271         {
    272             m_rectWorking = new Rectangle(this.Width / 2 - this.Width / 8, this.Width / 4, this.Width / 4, this.Height - this.Width / 2);
    273             m_rectLeft = new Rectangle(0, m_rectWorking.Top + m_rectWorking.Width / 2, (this.Width - this.Width / 4) / 2 - 2, m_rectWorking.Height - m_rectWorking.Width * 2);
    274             m_rectRight = new Rectangle(this.Width - (this.Width - this.Width / 4) / 2 + 2, m_rectWorking.Top + m_rectWorking.Width / 2, (this.Width - this.Width / 4) / 2 - 2, m_rectWorking.Height - m_rectWorking.Width * 2);
    275         }
    276 
    277         /// <summary>
    278         /// 引发 <see cref="E:System.Windows.Forms.Control.Paint" /> 事件。
    279         /// </summary>
    280         /// <param name="e">包含事件数据的 <see cref="T:System.Windows.Forms.PaintEventArgs" /></param>
    281         protected override void OnPaint(PaintEventArgs e)
    282         {
    283             base.OnPaint(e);
    284             var g = e.Graphics;
    285             g.SetGDIHigh();
    286 
    287             //玻璃管管
    288             GraphicsPath path = new GraphicsPath();
    289             path.AddLine(m_rectWorking.Left, m_rectWorking.Bottom, m_rectWorking.Left, m_rectWorking.Top + m_rectWorking.Width / 2);
    290             path.AddArc(new Rectangle(m_rectWorking.Left, m_rectWorking.Top, m_rectWorking.Width, m_rectWorking.Width), 180, 180);
    291             path.AddLine(m_rectWorking.Right, m_rectWorking.Top + m_rectWorking.Width / 2, m_rectWorking.Right, m_rectWorking.Bottom);
    292             path.CloseAllFigures();
    293             g.FillPath(new SolidBrush(glassTubeColor), path);
    294 
    295             //底部
    296             var rectDi = new Rectangle(this.Width / 2 - m_rectWorking.Width, m_rectWorking.Bottom - m_rectWorking.Width - 2, m_rectWorking.Width * 2, m_rectWorking.Width * 2);
    297             g.FillEllipse(new SolidBrush(glassTubeColor), rectDi);
    298             g.FillEllipse(new SolidBrush(mercuryColor), new Rectangle(rectDi.Left + 4, rectDi.Top + 4, rectDi.Width - 8, rectDi.Height - 8));
    299 
    300             //刻度
    301             decimal decSplit = (maxValue - minValue) / splitCount;
    302             decimal decSplitHeight = m_rectLeft.Height / splitCount;
    303             for (int i = 0; i <= splitCount; i++)
    304             {
    305                 g.DrawLine(new Pen(new SolidBrush(ForeColor), 1), new PointF(m_rectLeft.Left + 2, (float)(m_rectLeft.Bottom - decSplitHeight * i)), new PointF(m_rectLeft.Right, (float)(m_rectLeft.Bottom - decSplitHeight * i)));
    306 
    307                 var valueLeft = (minValue + decSplit * i).ToString("0.##");
    308                 var sizeLeft = g.MeasureString(valueLeft, Font);
    309                 g.DrawString(valueLeft, Font, new SolidBrush(ForeColor), new PointF(m_rectLeft.Left, m_rectLeft.Bottom - (float)decSplitHeight * i - sizeLeft.Height - 1));
    310 
    311                 if (rightTemperatureUnit != TemperatureUnit.None)
    312                 {
    313                     g.DrawLine(new Pen(new SolidBrush(Color.Black), 1), new PointF(m_rectRight.Left + 2, (float)(m_rectRight.Bottom - decSplitHeight * i)), new PointF(m_rectRight.Right, (float)(m_rectRight.Bottom - decSplitHeight * i)));
    314                     var valueRight = GetRightValue(minValue + decSplit * i).ToString("0.##");
    315                     var sizeRight = g.MeasureString(valueRight, Font);
    316                     g.DrawString(valueRight, Font, new SolidBrush(ForeColor), new PointF(m_rectRight.Right - sizeRight.Width - 1, m_rectRight.Bottom - (float)decSplitHeight * i - sizeRight.Height - 1));
    317                 }
    318                 if (i != splitCount)
    319                 {
    320                     if (decSplitHeight > 40)
    321                     {
    322                         var decSp1 = decSplitHeight / 10;
    323                         for (int j = 1; j < 10; j++)
    324                         {
    325                             if (j == 5)
    326                             {
    327                                 g.DrawLine(new Pen(new SolidBrush(ForeColor), 1), new PointF(m_rectLeft.Right - 10, (m_rectLeft.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))), new PointF(m_rectLeft.Right, (m_rectLeft.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))));
    328                                 if (rightTemperatureUnit != TemperatureUnit.None)
    329                                 {
    330                                     g.DrawLine(new Pen(new SolidBrush(ForeColor), 1), new PointF(m_rectRight.Left + 10, (m_rectRight.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))), new PointF(m_rectRight.Left, (m_rectRight.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))));
    331                                 }
    332                             }
    333                             else
    334                             {
    335                                 g.DrawLine(new Pen(new SolidBrush(ForeColor), 1), new PointF(m_rectLeft.Right - 5, (m_rectLeft.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))), new PointF(m_rectLeft.Right, (m_rectLeft.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))));
    336                                 if (rightTemperatureUnit != TemperatureUnit.None)
    337                                 {
    338                                     g.DrawLine(new Pen(new SolidBrush(ForeColor), 1), new PointF(m_rectRight.Left + 5, (m_rectRight.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))), new PointF(m_rectRight.Left, (m_rectRight.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))));
    339                                 }
    340                             }
    341                         }
    342                     }
    343                     else if (decSplitHeight > 10)
    344                     {
    345                         g.DrawLine(new Pen(new SolidBrush(ForeColor), 1), new PointF(m_rectLeft.Right - 5, (m_rectLeft.Bottom - (float)decSplitHeight * i - (float)decSplitHeight / 2)), new PointF(m_rectLeft.Right, (m_rectLeft.Bottom - (float)decSplitHeight * i - (float)decSplitHeight / 2)));
    346                         if (rightTemperatureUnit != TemperatureUnit.None)
    347                         {
    348                             g.DrawLine(new Pen(new SolidBrush(ForeColor), 1), new PointF(m_rectRight.Left + 5, (m_rectRight.Bottom - (float)decSplitHeight * i - (float)decSplitHeight / 2)), new PointF(m_rectRight.Left, (m_rectRight.Bottom - (float)decSplitHeight * i - (float)decSplitHeight / 2)));
    349                         }
    350                     }
    351                 }
    352             }
    353             //单位
    354             string strLeftUnit = GetUnitChar(leftTemperatureUnit);
    355             g.DrawString(strLeftUnit, Font, new SolidBrush(ForeColor), new PointF(m_rectLeft.Left + 2, 2));
    356             if (rightTemperatureUnit != TemperatureUnit.None)
    357             {
    358                 string strRightUnit = GetUnitChar(rightTemperatureUnit);
    359                 var rightSize = g.MeasureString(strRightUnit, Font);
    360                 g.DrawString(strRightUnit, Font, new SolidBrush(ForeColor), new PointF(m_rectRight.Right - 2 - rightSize.Width, 2));
    361             }
    362             //
    363             float fltHeightValue = (float)(Value / (maxValue - minValue) * m_rectLeft.Height);
    364             RectangleF rectValue = new RectangleF(m_rectWorking.Left + 4, m_rectLeft.Top + (m_rectLeft.Height - fltHeightValue), m_rectWorking.Width - 8, fltHeightValue + (m_rectWorking.Height - m_rectWorking.Width / 2 - m_rectLeft.Height));
    365             g.FillRectangle(new SolidBrush(mercuryColor), rectValue);
    366 
    367 
    368             var sizeValue = g.MeasureString(m_value.ToString("0.##"), Font);
    369             g.DrawString(m_value.ToString("0.##"), Font, new SolidBrush(Color.White), new PointF(rectDi.Left + (rectDi.Width - sizeValue.Width) / 2, rectDi.Top + (rectDi.Height - sizeValue.Height) / 2 + 1));
    370         }
    371 
    372         private string GetUnitChar(TemperatureUnit unit)
    373         {
    374             string strUnit = "";
    375             switch (unit)
    376             {
    377                 case TemperatureUnit.C:
    378                     strUnit = "";
    379                     break;
    380                 case TemperatureUnit.F:
    381                     strUnit = "";
    382                     break;
    383                 case TemperatureUnit.K:
    384                     strUnit = "K";
    385                     break;
    386                 case TemperatureUnit.R:
    387                     strUnit = "°R";
    388                     break;
    389                 case TemperatureUnit.Re:
    390                     strUnit = "°Re";
    391                     break;
    392             }
    393             return strUnit;
    394         }
    395 
    396         private decimal GetRightValue(decimal decValue)
    397         {
    398             //先将左侧的换算为摄氏度
    399             var dec = decValue;
    400             switch (leftTemperatureUnit)
    401             {
    402                 case TemperatureUnit.F:
    403                     dec = (decValue - 32) / (9M / 5M);
    404                     break;
    405                 case TemperatureUnit.K:
    406                     dec = decValue - 273;
    407                     break;
    408                 case TemperatureUnit.R:
    409                     dec = decValue / (5M / 9M) - 273.15M;
    410                     break;
    411                 case TemperatureUnit.Re:
    412                     dec = decValue / 1.25M;
    413                     break;
    414                 default:
    415                     break;
    416             }
    417 
    418             switch (rightTemperatureUnit)
    419             {
    420                 case TemperatureUnit.C:
    421                     return dec;
    422                 case TemperatureUnit.F:
    423                     return 9M / 5M * dec + 32;
    424                 case TemperatureUnit.K:
    425                     return dec + 273;
    426                 case TemperatureUnit.R:
    427                     return (dec + 273.15M) * (5M / 9M);
    428                 case TemperatureUnit.Re:
    429                     return dec * 1.25M;
    430             }
    431             return decValue;
    432         }
    433     }
    434 
    435     /// <summary>
    436     /// Enum TemperatureUnit
    437     /// </summary>
    438     public enum TemperatureUnit
    439     {
    440         /// <summary>
    441         /// 不显示
    442         /// </summary>
    443         None,
    444         /// <summary>
    445         /// 摄氏度
    446         /// </summary>
    447         C,
    448         /// <summary>
    449         /// 华氏度
    450         /// </summary>
    451         F,
    452         /// <summary>
    453         /// 开氏度
    454         /// </summary>
    455         K,
    456         /// <summary>
    457         /// 兰氏度
    458         /// </summary>
    459         R,
    460         /// <summary>
    461         /// 列氏度
    462         /// </summary>
    463         Re
    464     }
    465 }
    View Code

    最后的话

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

  • 相关阅读:
    C# 文件绝对路径与相对路径的转换
    DevExpress TreeList 禁止节点拖动到其他节点上
    C# 通过KD树进行距离最近点的查找.
    C# 利用键值对取代Switch...Case语句
    C# 利用位运算传递多个参数方法
    Deepin安装node与npm
    python-demo:计算合格率
    SpringDataJpa在一对多、多对多关系映射时出现StackOverflowError
    npm install 问题汇总
    CentOS7 使用firewalld打开关闭防火墙与端口
  • 原文地址:https://www.cnblogs.com/bfyx/p/11498225.html
Copyright © 2020-2023  润新知