(六十四)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 ...
随机推荐
- 开发一个Spring Boot Starter!
在上一篇文章中,我们已经了解了一个starter实现自动配置的基本流程,在这一小结我们将复现上一过程,实现一个自定义的starter. 先来分析starter的需求: 在项目中添加自定义的starte ...
- Hadoop学习(5)-zookeeper的安装和命令行,java操作
zookeeper是干嘛的呢 Zookeeper的作用1.可以为客户端管理少量的数据kvkey:是以路径的形式表示的,那就意味着,各key之间有父子关系,比如/ 是顶层key用户建的key只能在/ 下 ...
- python编写环境(种类)
python编写环境(种类) 官方推荐 cpython 转成C的字节码 jython转成Java的字节码 ironpython转成C#字节码 pypy转换成动态编译 开发快,运行快
- 【转】linux tar.gz zip 解压缩 压缩命令
http://apps.hi.baidu.com/share/detail/37384818 download ADT link http://dl.google.com/android/ADT-0. ...
- zuul集成Sentinel最新的网关流控组件
一.说明 Sentinel 网关流控支持针对不同的路由和自定义的 API 分组进行流控,支持针对请求属性(如 URL 参数,Client IP,Header 等)进行流控.Sentinel 1.6.3 ...
- 委托和lambda表达式,Action和Func
1.为什么要用委托 我们为什么要有委托?任何东西存在即合理,不合理的也会被时间淘汰掉,委托既然存在肯定有存在的必要,我们来看一下什么时候可以用到委托. 接下来我们有个需求,就是调用一个方法,取出1-1 ...
- 十款强大的IDEA插件-Java开发者的利器
xl_echo编辑整理,欢迎转载,转载请声明文章来源.欢迎添加echo微信(微信号:t2421499075)交流学习. 百战不败,依不自称常胜,百败不颓,依能奋力前行.--这才是真正的堪称强大!! 插 ...
- Hey Future!
我是蒟蒻QWQ 本人一大蒟蒻 弱的一批 希望大家见谅
- idea中pom如何加载jar包依赖
1.需求分析 在特定需求的情况下,idea需要加载jar包,那么如何在idea中正确的配置jar依赖呢?今天博主就这个问题给大伙讲解下,希望对大伙有所帮助 2.实现方案①在工程src目录下新建l ...
- 关于《Selenium3自动化测试实战--基于python语言》
2016年1月,机缘巧合下我出版了<Selenium2自动化测试实战--基于python语言>这本书,当时写书的原因是,大部分讲Selenium的书并不讲编程语言和单元测试框,如果想在项目 ...