官网

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

用处及效果

准备工作

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

开始

添加一个类UCThermometer,继承UserControl

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

  public enum TemperatureUnit
{
/// <summary>
/// 不显示
/// </summary>
None,
/// <summary>
/// 摄氏度
/// </summary>
C,
/// <summary>
/// 华氏度
/// </summary>
F,
/// <summary>
/// 开氏度
/// </summary>
K,
/// <summary>
/// 兰氏度
/// </summary>
R,
/// <summary>
/// 列氏度
/// </summary>
Re
}

添加一些属性

 /// <summary>
/// The glass tube color
/// </summary>
private Color glassTubeColor = Color.FromArgb(, , ); /// <summary>
/// Gets or sets the color of the glass tube.
/// </summary>
/// <value>The color of the glass tube.</value>
[Description("玻璃管颜色"), Category("自定义")]
public Color GlassTubeColor
{
get { return glassTubeColor; }
set
{
glassTubeColor = value;
Refresh();
}
} /// <summary>
/// The mercury color
/// </summary>
private Color mercuryColor = Color.FromArgb(, , ); /// <summary>
/// Gets or sets the color of the mercury.
/// </summary>
/// <value>The color of the mercury.</value>
[Description("水印颜色"), Category("自定义")]
public Color MercuryColor
{
get { return mercuryColor; }
set
{
mercuryColor = value;
Refresh();
}
} /// <summary>
/// The minimum value
/// </summary>
private decimal minValue = ;
/// <summary>
/// 左侧刻度最小值
/// </summary>
/// <value>The minimum value.</value>
[Description("左侧刻度最小值"), Category("自定义")]
public decimal MinValue
{
get { return minValue; }
set
{
minValue = value;
Refresh();
}
} /// <summary>
/// The maximum value
/// </summary>
private decimal maxValue = ;
/// <summary>
/// 左侧刻度最大值
/// </summary>
/// <value>The maximum value.</value>
[Description("左侧刻度最大值"), Category("自定义")]
public decimal MaxValue
{
get { return maxValue; }
set
{
maxValue = value;
Refresh();
}
} /// <summary>
/// The m value
/// </summary>
private decimal m_value = ;
/// <summary>
/// 左侧刻度值
/// </summary>
/// <value>The value.</value>
[Description("左侧刻度值"), Category("自定义")]
public decimal Value
{
get { return m_value; }
set
{
m_value = value;
Refresh();
}
} /// <summary>
/// The split count
/// </summary>
private int splitCount = ;
/// <summary>
/// 刻度分隔份数
/// </summary>
/// <value>The split count.</value>
[Description("刻度分隔份数"), Category("自定义")]
public int SplitCount
{
get { return splitCount; }
set
{
if (value <= )
return;
splitCount = 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();
}
} /// <summary>
/// 获取或设置控件的前景色。
/// </summary>
/// <value>The color of the fore.</value>
/// <PermissionSet>
/// <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
/// </PermissionSet>
[Description("获取或设置控件的文字及刻度颜色"), Category("自定义")]
public override System.Drawing.Color ForeColor
{
get
{
return base.ForeColor;
}
set
{
base.ForeColor = value;
Refresh();
}
} /// <summary>
/// The left temperature unit
/// </summary>
private TemperatureUnit leftTemperatureUnit = TemperatureUnit.C;
/// <summary>
/// 左侧刻度单位,不可为none
/// </summary>
/// <value>The left temperature unit.</value>
[Description("左侧刻度单位,不可为none"), Category("自定义")]
public TemperatureUnit LeftTemperatureUnit
{
get { return leftTemperatureUnit; }
set
{
if (value == TemperatureUnit.None)
return;
leftTemperatureUnit = value;
Refresh();
}
} /// <summary>
/// The right temperature unit
/// </summary>
private TemperatureUnit rightTemperatureUnit = TemperatureUnit.C;
/// <summary>
/// 右侧刻度单位,当为none时,不显示
/// </summary>
/// <value>The right temperature unit.</value>
[Description("右侧刻度单位,当为none时,不显示"), Category("自定义")]
public TemperatureUnit RightTemperatureUnit
{
get { return rightTemperatureUnit; }
set
{
rightTemperatureUnit = value;
Refresh();
}
} /// <summary>
/// The m rect working
/// </summary>
Rectangle m_rectWorking;
/// <summary>
/// The m rect left
/// </summary>
Rectangle m_rectLeft;
/// <summary>
/// The m rect right
/// </summary>
Rectangle m_rectRight;

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

  void UCThermometer_SizeChanged(object sender, EventArgs e)
{
m_rectWorking = new Rectangle(this.Width / - this.Width / , this.Width / , this.Width / , this.Height - this.Width / );
m_rectLeft = new Rectangle(, m_rectWorking.Top + m_rectWorking.Width / , (this.Width - this.Width / ) / - , m_rectWorking.Height - m_rectWorking.Width * );
m_rectRight = new Rectangle(this.Width - (this.Width - this.Width / ) / + , m_rectWorking.Top + m_rectWorking.Width / , (this.Width - this.Width / ) / - , m_rectWorking.Height - m_rectWorking.Width * );
}

重绘

  protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
var g = e.Graphics;
g.SetGDIHigh(); //玻璃管管
GraphicsPath path = new GraphicsPath();
path.AddLine(m_rectWorking.Left, m_rectWorking.Bottom, m_rectWorking.Left, m_rectWorking.Top + m_rectWorking.Width / );
path.AddArc(new Rectangle(m_rectWorking.Left, m_rectWorking.Top, m_rectWorking.Width, m_rectWorking.Width), , );
path.AddLine(m_rectWorking.Right, m_rectWorking.Top + m_rectWorking.Width / , m_rectWorking.Right, m_rectWorking.Bottom);
path.CloseAllFigures();
g.FillPath(new SolidBrush(glassTubeColor), path); //底部
var rectDi = new Rectangle(this.Width / - m_rectWorking.Width, m_rectWorking.Bottom - m_rectWorking.Width - , m_rectWorking.Width * , m_rectWorking.Width * );
g.FillEllipse(new SolidBrush(glassTubeColor), rectDi);
g.FillEllipse(new SolidBrush(mercuryColor), new Rectangle(rectDi.Left + , rectDi.Top + , rectDi.Width - , rectDi.Height - )); //刻度
decimal decSplit = (maxValue - minValue) / splitCount;
decimal decSplitHeight = m_rectLeft.Height / splitCount;
for (int i = ; i <= splitCount; i++)
{
g.DrawLine(new Pen(new SolidBrush(ForeColor), ), new PointF(m_rectLeft.Left + , (float)(m_rectLeft.Bottom - decSplitHeight * i)), new PointF(m_rectLeft.Right, (float)(m_rectLeft.Bottom - decSplitHeight * i))); var valueLeft = (minValue + decSplit * i).ToString("0.##");
var sizeLeft = g.MeasureString(valueLeft, Font);
g.DrawString(valueLeft, Font, new SolidBrush(ForeColor), new PointF(m_rectLeft.Left, m_rectLeft.Bottom - (float)decSplitHeight * i - sizeLeft.Height - )); if (rightTemperatureUnit != TemperatureUnit.None)
{
g.DrawLine(new Pen(new SolidBrush(Color.Black), ), new PointF(m_rectRight.Left + , (float)(m_rectRight.Bottom - decSplitHeight * i)), new PointF(m_rectRight.Right, (float)(m_rectRight.Bottom - decSplitHeight * i)));
var valueRight = GetRightValue(minValue + decSplit * i).ToString("0.##");
var sizeRight = g.MeasureString(valueRight, Font);
g.DrawString(valueRight, Font, new SolidBrush(ForeColor), new PointF(m_rectRight.Right - sizeRight.Width - , m_rectRight.Bottom - (float)decSplitHeight * i - sizeRight.Height - ));
}
if (i != splitCount)
{
if (decSplitHeight > )
{
var decSp1 = decSplitHeight / ;
for (int j = ; j < ; j++)
{
if (j == )
{
g.DrawLine(new Pen(new SolidBrush(ForeColor), ), new PointF(m_rectLeft.Right - , (m_rectLeft.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))), new PointF(m_rectLeft.Right, (m_rectLeft.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))));
if (rightTemperatureUnit != TemperatureUnit.None)
{
g.DrawLine(new Pen(new SolidBrush(ForeColor), ), new PointF(m_rectRight.Left + , (m_rectRight.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))), new PointF(m_rectRight.Left, (m_rectRight.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))));
}
}
else
{
g.DrawLine(new Pen(new SolidBrush(ForeColor), ), new PointF(m_rectLeft.Right - , (m_rectLeft.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))), new PointF(m_rectLeft.Right, (m_rectLeft.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))));
if (rightTemperatureUnit != TemperatureUnit.None)
{
g.DrawLine(new Pen(new SolidBrush(ForeColor), ), new PointF(m_rectRight.Left + , (m_rectRight.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))), new PointF(m_rectRight.Left, (m_rectRight.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))));
}
}
}
}
else if (decSplitHeight > )
{
g.DrawLine(new Pen(new SolidBrush(ForeColor), ), new PointF(m_rectLeft.Right - , (m_rectLeft.Bottom - (float)decSplitHeight * i - (float)decSplitHeight / )), new PointF(m_rectLeft.Right, (m_rectLeft.Bottom - (float)decSplitHeight * i - (float)decSplitHeight / )));
if (rightTemperatureUnit != TemperatureUnit.None)
{
g.DrawLine(new Pen(new SolidBrush(ForeColor), ), new PointF(m_rectRight.Left + , (m_rectRight.Bottom - (float)decSplitHeight * i - (float)decSplitHeight / )), new PointF(m_rectRight.Left, (m_rectRight.Bottom - (float)decSplitHeight * i - (float)decSplitHeight / )));
}
}
}
}
//单位
string strLeftUnit = GetUnitChar(leftTemperatureUnit);
g.DrawString(strLeftUnit, Font, new SolidBrush(ForeColor), new PointF(m_rectLeft.Left + , ));
if (rightTemperatureUnit != TemperatureUnit.None)
{
string strRightUnit = GetUnitChar(rightTemperatureUnit);
var rightSize = g.MeasureString(strRightUnit, Font);
g.DrawString(strRightUnit, Font, new SolidBrush(ForeColor), new PointF(m_rectRight.Right - - rightSize.Width, ));
}
//值
float fltHeightValue = (float)(Value / (maxValue - minValue) * m_rectLeft.Height);
RectangleF rectValue = new RectangleF(m_rectWorking.Left + , m_rectLeft.Top + (m_rectLeft.Height - fltHeightValue), m_rectWorking.Width - , fltHeightValue + (m_rectWorking.Height - m_rectWorking.Width / - m_rectLeft.Height));
g.FillRectangle(new SolidBrush(mercuryColor), rectValue); var sizeValue = g.MeasureString(m_value.ToString("0.##"), Font);
g.DrawString(m_value.ToString("0.##"), Font, new SolidBrush(Color.White), new PointF(rectDi.Left + (rectDi.Width - sizeValue.Width) / , rectDi.Top + (rectDi.Height - sizeValue.Height) / + ));
}

辅助函数

 private string GetUnitChar(TemperatureUnit unit)
{
string strUnit = "℃";
switch (unit)
{
case TemperatureUnit.C:
strUnit = "℃";
break;
case TemperatureUnit.F:
strUnit = "℉";
break;
case TemperatureUnit.K:
strUnit = "K";
break;
case TemperatureUnit.R:
strUnit = "°R";
break;
case TemperatureUnit.Re:
strUnit = "°Re";
break;
}
return strUnit;
} private decimal GetRightValue(decimal decValue)
{
//先将左侧的换算为摄氏度
var dec = decValue;
switch (leftTemperatureUnit)
{
case TemperatureUnit.F:
dec = (decValue - ) / (9M / 5M);
break;
case TemperatureUnit.K:
dec = decValue - ;
break;
case TemperatureUnit.R:
dec = decValue / (5M / 9M) - 273.15M;
break;
case TemperatureUnit.Re:
dec = decValue / 1.25M;
break;
default:
break;
} switch (rightTemperatureUnit)
{
case TemperatureUnit.C:
return dec;
case TemperatureUnit.F:
return 9M / 5M * dec + ;
case TemperatureUnit.K:
return dec + ;
case TemperatureUnit.R:
return (dec + 273.15M) * (5M / 9M);
case TemperatureUnit.Re:
return dec * 1.25M;
}
return decValue;
}

完整代码

 // ***********************************************************************
// Assembly : HZH_Controls
// Created : 2019-09-10
//
// ***********************************************************************
// <copyright file="UCThermometer.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 UCThermometer.
/// Implements the <see cref="System.Windows.Forms.UserControl" />
/// </summary>
/// <seealso cref="System.Windows.Forms.UserControl" />
public class UCThermometer : UserControl
{
/// <summary>
/// The glass tube color
/// </summary>
private Color glassTubeColor = Color.FromArgb(, , ); /// <summary>
/// Gets or sets the color of the glass tube.
/// </summary>
/// <value>The color of the glass tube.</value>
[Description("玻璃管颜色"), Category("自定义")]
public Color GlassTubeColor
{
get { return glassTubeColor; }
set
{
glassTubeColor = value;
Refresh();
}
} /// <summary>
/// The mercury color
/// </summary>
private Color mercuryColor = Color.FromArgb(, , ); /// <summary>
/// Gets or sets the color of the mercury.
/// </summary>
/// <value>The color of the mercury.</value>
[Description("水印颜色"), Category("自定义")]
public Color MercuryColor
{
get { return mercuryColor; }
set
{
mercuryColor = value;
Refresh();
}
} /// <summary>
/// The minimum value
/// </summary>
private decimal minValue = ;
/// <summary>
/// 左侧刻度最小值
/// </summary>
/// <value>The minimum value.</value>
[Description("左侧刻度最小值"), Category("自定义")]
public decimal MinValue
{
get { return minValue; }
set
{
minValue = value;
Refresh();
}
} /// <summary>
/// The maximum value
/// </summary>
private decimal maxValue = ;
/// <summary>
/// 左侧刻度最大值
/// </summary>
/// <value>The maximum value.</value>
[Description("左侧刻度最大值"), Category("自定义")]
public decimal MaxValue
{
get { return maxValue; }
set
{
maxValue = value;
Refresh();
}
} /// <summary>
/// The m value
/// </summary>
private decimal m_value = ;
/// <summary>
/// 左侧刻度值
/// </summary>
/// <value>The value.</value>
[Description("左侧刻度值"), Category("自定义")]
public decimal Value
{
get { return m_value; }
set
{
m_value = value;
Refresh();
}
} /// <summary>
/// The split count
/// </summary>
private int splitCount = ;
/// <summary>
/// 刻度分隔份数
/// </summary>
/// <value>The split count.</value>
[Description("刻度分隔份数"), Category("自定义")]
public int SplitCount
{
get { return splitCount; }
set
{
if (value <= )
return;
splitCount = 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();
}
} /// <summary>
/// 获取或设置控件的前景色。
/// </summary>
/// <value>The color of the fore.</value>
/// <PermissionSet>
/// <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
/// </PermissionSet>
[Description("获取或设置控件的文字及刻度颜色"), Category("自定义")]
public override System.Drawing.Color ForeColor
{
get
{
return base.ForeColor;
}
set
{
base.ForeColor = value;
Refresh();
}
} /// <summary>
/// The left temperature unit
/// </summary>
private TemperatureUnit leftTemperatureUnit = TemperatureUnit.C;
/// <summary>
/// 左侧刻度单位,不可为none
/// </summary>
/// <value>The left temperature unit.</value>
[Description("左侧刻度单位,不可为none"), Category("自定义")]
public TemperatureUnit LeftTemperatureUnit
{
get { return leftTemperatureUnit; }
set
{
if (value == TemperatureUnit.None)
return;
leftTemperatureUnit = value;
Refresh();
}
} /// <summary>
/// The right temperature unit
/// </summary>
private TemperatureUnit rightTemperatureUnit = TemperatureUnit.C;
/// <summary>
/// 右侧刻度单位,当为none时,不显示
/// </summary>
/// <value>The right temperature unit.</value>
[Description("右侧刻度单位,当为none时,不显示"), Category("自定义")]
public TemperatureUnit RightTemperatureUnit
{
get { return rightTemperatureUnit; }
set
{
rightTemperatureUnit = value;
Refresh();
}
} /// <summary>
/// The m rect working
/// </summary>
Rectangle m_rectWorking;
/// <summary>
/// The m rect left
/// </summary>
Rectangle m_rectLeft;
/// <summary>
/// The m rect right
/// </summary>
Rectangle m_rectRight;
/// <summary>
/// Initializes a new instance of the <see cref="UCThermometer"/> class.
/// </summary>
public UCThermometer()
{
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.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.SizeChanged += UCThermometer_SizeChanged;
this.Size = new Size(, );
} /// <summary>
/// Handles the SizeChanged event of the UCThermometer control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
void UCThermometer_SizeChanged(object sender, EventArgs e)
{
m_rectWorking = new Rectangle(this.Width / - this.Width / , this.Width / , this.Width / , this.Height - this.Width / );
m_rectLeft = new Rectangle(, m_rectWorking.Top + m_rectWorking.Width / , (this.Width - this.Width / ) / - , m_rectWorking.Height - m_rectWorking.Width * );
m_rectRight = new Rectangle(this.Width - (this.Width - this.Width / ) / + , m_rectWorking.Top + m_rectWorking.Width / , (this.Width - this.Width / ) / - , m_rectWorking.Height - m_rectWorking.Width * );
} /// <summary>
/// 引发 <see cref="E:System.Windows.Forms.Control.Paint" /> 事件。
/// </summary>
/// <param name="e">包含事件数据的 <see cref="T:System.Windows.Forms.PaintEventArgs" />。</param>
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
var g = e.Graphics;
g.SetGDIHigh(); //玻璃管管
GraphicsPath path = new GraphicsPath();
path.AddLine(m_rectWorking.Left, m_rectWorking.Bottom, m_rectWorking.Left, m_rectWorking.Top + m_rectWorking.Width / );
path.AddArc(new Rectangle(m_rectWorking.Left, m_rectWorking.Top, m_rectWorking.Width, m_rectWorking.Width), , );
path.AddLine(m_rectWorking.Right, m_rectWorking.Top + m_rectWorking.Width / , m_rectWorking.Right, m_rectWorking.Bottom);
path.CloseAllFigures();
g.FillPath(new SolidBrush(glassTubeColor), path); //底部
var rectDi = new Rectangle(this.Width / - m_rectWorking.Width, m_rectWorking.Bottom - m_rectWorking.Width - , m_rectWorking.Width * , m_rectWorking.Width * );
g.FillEllipse(new SolidBrush(glassTubeColor), rectDi);
g.FillEllipse(new SolidBrush(mercuryColor), new Rectangle(rectDi.Left + , rectDi.Top + , rectDi.Width - , rectDi.Height - )); //刻度
decimal decSplit = (maxValue - minValue) / splitCount;
decimal decSplitHeight = m_rectLeft.Height / splitCount;
for (int i = ; i <= splitCount; i++)
{
g.DrawLine(new Pen(new SolidBrush(ForeColor), ), new PointF(m_rectLeft.Left + , (float)(m_rectLeft.Bottom - decSplitHeight * i)), new PointF(m_rectLeft.Right, (float)(m_rectLeft.Bottom - decSplitHeight * i))); var valueLeft = (minValue + decSplit * i).ToString("0.##");
var sizeLeft = g.MeasureString(valueLeft, Font);
g.DrawString(valueLeft, Font, new SolidBrush(ForeColor), new PointF(m_rectLeft.Left, m_rectLeft.Bottom - (float)decSplitHeight * i - sizeLeft.Height - )); if (rightTemperatureUnit != TemperatureUnit.None)
{
g.DrawLine(new Pen(new SolidBrush(Color.Black), ), new PointF(m_rectRight.Left + , (float)(m_rectRight.Bottom - decSplitHeight * i)), new PointF(m_rectRight.Right, (float)(m_rectRight.Bottom - decSplitHeight * i)));
var valueRight = GetRightValue(minValue + decSplit * i).ToString("0.##");
var sizeRight = g.MeasureString(valueRight, Font);
g.DrawString(valueRight, Font, new SolidBrush(ForeColor), new PointF(m_rectRight.Right - sizeRight.Width - , m_rectRight.Bottom - (float)decSplitHeight * i - sizeRight.Height - ));
}
if (i != splitCount)
{
if (decSplitHeight > )
{
var decSp1 = decSplitHeight / ;
for (int j = ; j < ; j++)
{
if (j == )
{
g.DrawLine(new Pen(new SolidBrush(ForeColor), ), new PointF(m_rectLeft.Right - , (m_rectLeft.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))), new PointF(m_rectLeft.Right, (m_rectLeft.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))));
if (rightTemperatureUnit != TemperatureUnit.None)
{
g.DrawLine(new Pen(new SolidBrush(ForeColor), ), new PointF(m_rectRight.Left + , (m_rectRight.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))), new PointF(m_rectRight.Left, (m_rectRight.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))));
}
}
else
{
g.DrawLine(new Pen(new SolidBrush(ForeColor), ), new PointF(m_rectLeft.Right - , (m_rectLeft.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))), new PointF(m_rectLeft.Right, (m_rectLeft.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))));
if (rightTemperatureUnit != TemperatureUnit.None)
{
g.DrawLine(new Pen(new SolidBrush(ForeColor), ), new PointF(m_rectRight.Left + , (m_rectRight.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))), new PointF(m_rectRight.Left, (m_rectRight.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))));
}
}
}
}
else if (decSplitHeight > )
{
g.DrawLine(new Pen(new SolidBrush(ForeColor), ), new PointF(m_rectLeft.Right - , (m_rectLeft.Bottom - (float)decSplitHeight * i - (float)decSplitHeight / )), new PointF(m_rectLeft.Right, (m_rectLeft.Bottom - (float)decSplitHeight * i - (float)decSplitHeight / )));
if (rightTemperatureUnit != TemperatureUnit.None)
{
g.DrawLine(new Pen(new SolidBrush(ForeColor), ), new PointF(m_rectRight.Left + , (m_rectRight.Bottom - (float)decSplitHeight * i - (float)decSplitHeight / )), new PointF(m_rectRight.Left, (m_rectRight.Bottom - (float)decSplitHeight * i - (float)decSplitHeight / )));
}
}
}
}
//单位
string strLeftUnit = GetUnitChar(leftTemperatureUnit);
g.DrawString(strLeftUnit, Font, new SolidBrush(ForeColor), new PointF(m_rectLeft.Left + , ));
if (rightTemperatureUnit != TemperatureUnit.None)
{
string strRightUnit = GetUnitChar(rightTemperatureUnit);
var rightSize = g.MeasureString(strRightUnit, Font);
g.DrawString(strRightUnit, Font, new SolidBrush(ForeColor), new PointF(m_rectRight.Right - - rightSize.Width, ));
}
//值
float fltHeightValue = (float)(Value / (maxValue - minValue) * m_rectLeft.Height);
RectangleF rectValue = new RectangleF(m_rectWorking.Left + , m_rectLeft.Top + (m_rectLeft.Height - fltHeightValue), m_rectWorking.Width - , fltHeightValue + (m_rectWorking.Height - m_rectWorking.Width / - m_rectLeft.Height));
g.FillRectangle(new SolidBrush(mercuryColor), rectValue); var sizeValue = g.MeasureString(m_value.ToString("0.##"), Font);
g.DrawString(m_value.ToString("0.##"), Font, new SolidBrush(Color.White), new PointF(rectDi.Left + (rectDi.Width - sizeValue.Width) / , rectDi.Top + (rectDi.Height - sizeValue.Height) / + ));
} private string GetUnitChar(TemperatureUnit unit)
{
string strUnit = "℃";
switch (unit)
{
case TemperatureUnit.C:
strUnit = "℃";
break;
case TemperatureUnit.F:
strUnit = "℉";
break;
case TemperatureUnit.K:
strUnit = "K";
break;
case TemperatureUnit.R:
strUnit = "°R";
break;
case TemperatureUnit.Re:
strUnit = "°Re";
break;
}
return strUnit;
} private decimal GetRightValue(decimal decValue)
{
//先将左侧的换算为摄氏度
var dec = decValue;
switch (leftTemperatureUnit)
{
case TemperatureUnit.F:
dec = (decValue - ) / (9M / 5M);
break;
case TemperatureUnit.K:
dec = decValue - ;
break;
case TemperatureUnit.R:
dec = decValue / (5M / 9M) - 273.15M;
break;
case TemperatureUnit.Re:
dec = decValue / 1.25M;
break;
default:
break;
} switch (rightTemperatureUnit)
{
case TemperatureUnit.C:
return dec;
case TemperatureUnit.F:
return 9M / 5M * dec + ;
case TemperatureUnit.K:
return dec + ;
case TemperatureUnit.R:
return (dec + 273.15M) * (5M / 9M);
case TemperatureUnit.Re:
return dec * 1.25M;
}
return decValue;
}
} /// <summary>
/// Enum TemperatureUnit
/// </summary>
public enum TemperatureUnit
{
/// <summary>
/// 不显示
/// </summary>
None,
/// <summary>
/// 摄氏度
/// </summary>
C,
/// <summary>
/// 华氏度
/// </summary>
F,
/// <summary>
/// 开氏度
/// </summary>
K,
/// <summary>
/// 兰氏度
/// </summary>
R,
/// <summary>
/// 列氏度
/// </summary>
Re
}
}

最后的话

如果你喜欢的话,请到 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精讲—elasticsearch(搜索引擎)的mapping映射管理

    第三百六十四节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)的mapping映射管理 1.映射(mapping)介绍 映射:创建索引的时候,可以预先定义字 ...

  3. Gradle 1.12用户指南翻译——第六十四章. 发布到Ivy(新)

    其他章节的翻译请参见:http://blog.csdn.net/column/details/gradle-translation.html翻译项目请关注Github上的地址:https://gith ...

  4. “全栈2019”Java第六十四章:接口与静态方法详解

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

  5. 孤荷凌寒自学python第六十四天学习mongoDB的基本操作并进行简单封装3

    孤荷凌寒自学python第六十四天学习mongoDB的基本操作并进行简单封装3 (完整学习过程屏幕记录视频地址在文末) 今天是学习mongoDB数据库的第十天. 今天继续学习mongoDB的简单操作, ...

  6. SpringBoot进阶教程(六十四)注解大全

    在Spring1.x时代,还没出现注解,需要大量xml配置文件并在内部编写大量bean标签.Java5推出新特性annotation,为spring的更新奠定了基础.从Spring 2.X开始spri ...

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

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

  8. (六十七)c#Winform自定义控件-柱状图

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

  9. OpenCV开发笔记(六十四):红胖子8分钟带你深入了解SURF特征点(图文并茂+浅显易懂+程序源码)

    若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...

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

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

随机推荐

  1. 9-2、大型项目的接口自动化实践记录----递归判断两个json串是否相等

    1.已知json串构成的情况下判断 先构造一下场景,假设已经把各个数据都移除掉不对比的字段 图1 预期.实际结果,复杂接口返回多层嵌套json时,同下 图2 预期.实际结果值为:{child_json ...

  2. webupload项目中使用

    目前项目需要一个多图上传的功能,使用LayUI并也是可以实现多图上传的,但是没有图片删除功能,参考了一下网上多图上传的插件,选择了WebUpload进行功能开发. 然而不幸的是,官方的插件并不带UI界 ...

  3. iView 实现可编辑表格

    create at: 2019-02-20 组件 <i-table highlight-row ref="currentRowTable" :columns="co ...

  4. python --- 零碎

    1.匿名输出: lambda x : print(x))(100) #冒号前输入量 ,冒号后是输出量结果:100 2.导入调用其他python文件: test1.py #第一个python文件 def ...

  5. 洛谷 P2044 [NOI2012]随机数生成器

    题意简述 读入X[0], m, a, c, n和g $ X[n+1]=(a*X[n]+c)\mod m $ 求X数列的第n项对g取余的值. 题解思路 矩阵加速 设\[ F=\begin{bmatrix ...

  6. Linux与Unix到底有什么不同?

    来自:开源中国 原文:Linux vs. Unix: What's the difference? 链接: https://opensource.com/article/18/5/difference ...

  7. python学习之并发编程(理论部分)

    第一章 操作系统 管理控制协调计算机中硬件与软件的关系. 操作系统的作用? 第一个作用: 将一些对硬件操作的复杂丑陋的接口,变成简单美丽的接口. open函数. 第二个作用: 多个进程抢占一个(CPU ...

  8. 曹工杂谈:Java 类加载还会死锁?这是什么情况?

    一.前言 今天事不是很多,正好在Java交流群里,看到一个比较有意思的问题,于是花了点时间研究了一下,这里做个简单的分享. 先贴一份测试代码,大家可以先猜测一下,执行结果会是怎样的: import j ...

  9. 二.安全NA之ASA基础

    一.ASA常用命令 show run interface #查看接口配置 show ip address #查看IP地址 show conn #查看防火墙状态信息,U代表up:I,代表进流量:O,代表 ...

  10. spring-boot-plus详细配置(五)

    spring-boot-plus详细配置 公共配置 application.yml