(六十四)c#Winform自定义控件-温度计(工业)
官网
前提
入行已经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自定义控件-温度计(工业)的更多相关文章
- (六十)c#Winform自定义控件-鼓风机(工业)
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...
- 第三百六十四节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)的mapping映射管理
第三百六十四节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)的mapping映射管理 1.映射(mapping)介绍 映射:创建索引的时候,可以预先定义字 ...
- Gradle 1.12用户指南翻译——第六十四章. 发布到Ivy(新)
其他章节的翻译请参见:http://blog.csdn.net/column/details/gradle-translation.html翻译项目请关注Github上的地址:https://gith ...
- “全栈2019”Java第六十四章:接口与静态方法详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- 孤荷凌寒自学python第六十四天学习mongoDB的基本操作并进行简单封装3
孤荷凌寒自学python第六十四天学习mongoDB的基本操作并进行简单封装3 (完整学习过程屏幕记录视频地址在文末) 今天是学习mongoDB数据库的第十天. 今天继续学习mongoDB的简单操作, ...
- SpringBoot进阶教程(六十四)注解大全
在Spring1.x时代,还没出现注解,需要大量xml配置文件并在内部编写大量bean标签.Java5推出新特性annotation,为spring的更新奠定了基础.从Spring 2.X开始spri ...
- (三十)c#Winform自定义控件-文本框(三)
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...
- (六十七)c#Winform自定义控件-柱状图
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...
- OpenCV开发笔记(六十四):红胖子8分钟带你深入了解SURF特征点(图文并茂+浅显易懂+程序源码)
若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...
- (二十)c#Winform自定义控件-有后退的窗体
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...
随机推荐
- 8.源码分析---从设计模式中看SOFARPC中的EventBus?
我们在前面分析客户端引用的时候会看到如下这段代码: // 产生开始调用事件 if (EventBus.isEnable(ClientStartInvokeEvent.class)) { EventBu ...
- java学习-NIO(二)Buffer
当我们需要与 NIO Channel 进行交互时, 我们就需要使用到 NIO Buffer, 即数据从 Buffer读取到 Channel 中, 并且从 Channel 中写入到 Buffer 中.缓 ...
- Java——数据结构(链表)
链表,可扩展长度,泛型. public class Link { Node header = null; //头结点 int length;//当前链表长度 class Node { Node nex ...
- 工作中常见的五种技术leader
力不从心型 在工作中有种技术leader,总认为自己是最好的.在方案设计的时候,自己有一种方案,下属有一种方案.leader非要别人听他的.如果两种方案没有优劣之分,比较建议的做法是让真正实施的人按照 ...
- Go_笔试题记录-指针与值类型实现接口的区别
1.如果Add函数的调用代码为: func main() { var a Integer = 1 var b Integer = 2 var i interface{} = &a sum := ...
- hbase集群region数量和大小的影响
1.Region数量的影响 通常较少的region数量可使群集运行的更加平稳,官方指出每个RegionServer大约100个regions的时候效果最好,理由如下: 1)Hbase的一个特性MSLA ...
- 使用.Net Core CLI命令dotnet new创建自定义模板
文章起源来自一篇博客:使用 .NET CORE 创建 项目模板,模板项目,Template - DeepThought - 博客园 之前使用Abp的时候就很认同Abp创建模板项目的方式.想不到.Net ...
- Spring中jdbcTemplate的用法实例
一.首先配置JdbcTemplate: 要使用Jdbctemplate 对象来完成jdbc 操作.通常情况下,有三种种方式得到JdbcTemplate 对象. 第一种方式:我们可以在自己定 ...
- BeanUtils开发包的使用
对内省技术有了一定的了解之后,我们就可以来学习一下BeanUtils开发包的使用了. 我们先假设一个情景,有一个JSP文件,如果要将该JSP文件中表单数据封装到Servlet文件应该怎么办?此时方法显 ...
- SpringBoot Mybatis解决使用PageHelper一对多分页问题
一般来说使用 PageHelper 能解决绝大多数的分页问题,相关使用可在博客园上搜索,能找到很多资料. 之前我在做SpringBoot 项目时遇到这样一个问题,就是当一对多联合查询时需要分页的情况下 ...