仓库温度监控系统重有个控件,就是温度监控,还是比较精美的,那么我们来看看制作的要点有哪些。
前面我们讨论过布局和圆角按钮。这节主要关注温度计控件
1. 布局: 两个Panel将界面分位上下两个部分,Dock.Top Dock.Fill分别设置给他们。
2. 温度按钮采用的有自定义的圆角按钮
3. 温度计控件
从设置部分,我们可以看到最重要的几个属性是:
Value=10
MaxValue=50
MercuryColor 水银颜色
GlassTubeColor 玻璃管颜色
//
// uTemperValue
//
this.uTemperValue.BMaxValue = new decimal(new int[] {
30,
0,
0,
0});
this.uTemperValue.BMinValue = new decimal(new int[] {
0,
0,
0,
0});
this.uTemperValue.Font = new System.Drawing.Font("宋体", 6.6F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.uTemperValue.ForeColor = System.Drawing.Color.White;
this.uTemperValue.GlassTubeColor = System.Drawing.Color.FromArgb(((int)(((byte)(211)))), ((int)(((byte)(211)))), ((int)(((byte)(211)))));
this.uTemperValue.LeftTemperatureUnit = STMS.STMSApp.UControls.UThermometer.TemperatureUnit.C;
this.uTemperValue.Location = new System.Drawing.Point(254, 6);
this.uTemperValue.MaxValue = new decimal(new int[] {
50,
0,
0,
0});
this.uTemperValue.MercuryColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(77)))), ((int)(((byte)(59)))));
this.uTemperValue.MinValue = new decimal(new int[] {
0,
0,
0,
0});
this.uTemperValue.Name = "uTemperValue";
this.uTemperValue.Size = new System.Drawing.Size(79, 150);
this.uTemperValue.SpCount = 5;
this.uTemperValue.TabIndex = 3;
this.uTemperValue.Value = new decimal(new int[] {
10,
0,
0,
0});
this.uTemperValue.ValueColor = System.Drawing.Color.White;
this.uTemperValue.ValueFont = new System.Drawing.Font("宋体", 7.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
//
// SRTemperLight
//
this.SRTemperLight.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(137)))), ((int)(((byte)(201)))), ((int)(((byte)(151)))));
this.SRTemperLight.Location = new System.Drawing.Point(110, 117);
this.SRTemperLight.Name = "SRTemperLight";
this.SRTemperLight.Size = new System.Drawing.Size(20, 20);
this.SRTemperLight.TabIndex = 2;
4. 温度计控件源码
public partial class UThermometer : UserControl
{
public UThermometer()
{
InitializeComponent();
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.Size = new Size(60, 200);
}
private Color glassTubeColor = Color.FromArgb(211, 211, 211);
[Description("玻璃管颜色"), Category("自定义")]
public Color GlassTubeColor
{
get { return glassTubeColor; }
set
{
glassTubeColor = value;
Refresh();
}
}
private Color mercuryColor = Color.FromArgb(255, 77, 59);
[Description("水银颜色"), Category("自定义")]
public Color MercuryColor
{
get { return mercuryColor; }
set
{
mercuryColor = value;
Refresh();
}
}
private decimal minValue = 0;
[Description("最小值"), Category("自定义")]
public decimal MinValue
{
get { return minValue; }
set
{
minValue = value;
Refresh();
}
}
private decimal maxValue = 50;
[Description("最大值"), Category("自定义")]
public decimal MaxValue
{
get { return maxValue; }
set
{
maxValue = value;
Refresh();
}
}
private decimal mValue = 10;
[Description("刻度值"), Category("自定义")]
public decimal Value
{
get { return mValue; }
set
{
mValue = value;
Refresh();
}
}
private int spCount = 6;
[Description("分隔份数"), Category("自定义")]
public int SpCount
{
get { return spCount; }
set
{
if (value <= 0)
return;
spCount = value;
Refresh();
}
}
[Description("获取或设置控件显示的文字的字体"), Category("自定义")]
public override Font Font
{
get
{
return base.Font;
}
set
{
base.Font = value;
Refresh();
}
}
[Description("获取或设置控件的文字及刻度颜色"), Category("自定义")]
public override System.Drawing.Color ForeColor
{
get
{
return base.ForeColor;
}
set
{
base.ForeColor = value;
Refresh();
}
}
private Color valueColor = Color.White;
[Description("温度值的文本颜色"), Category("自定义")]
public Color ValueColor
{
get
{
return valueColor;
}
set
{
valueColor = value;
Refresh();
}
}
private Font valueFont = new Font("宋体", 10);
public Font ValueFont
{
get
{
return valueFont;
}
set
{
valueFont = value;
Refresh();
}
}
private TemperatureUnit leftTemperatureUnit = TemperatureUnit.C;
[Description("左侧刻度单位,不可为none"), Category("自定义")]
public TemperatureUnit LeftTemperatureUnit
{
get { return leftTemperatureUnit; }
set
{
if (value == TemperatureUnit.None)
return;
leftTemperatureUnit = value;
Refresh();
}
}
/// <summary>
/// 高温线的温度值
/// </summary>
public decimal bMaxValue;
public decimal BMaxValue
{
get { return bMaxValue; }
set
{
bMaxValue = value;
Refresh();
}
}
/// <summary>
///低温线的温度值
/// </summary>
public decimal bMinValue;
public decimal BMinValue
{
get { return bMinValue; }
set
{
bMinValue = value;
Refresh();
}
}
Rectangle m_rectWorking; //工作区
Rectangle m_rectLeft;//刻度区域
/// <summary>
/// 温度计单位
/// </summary>
public enum TemperatureUnit
{
/// <summary>
/// 不显示
/// </summary>
None,
/// <summary>
/// 摄氏度
/// </summary>
C,
/// <summary>
/// 华氏度
/// </summary>
F,
/// <summary>
/// 开氏度
/// </summary>
K,
/// <summary>
/// 兰氏度
/// </summary>
R,
/// <summary>
/// 列氏度
/// </summary>
Re
}
private void UThermometer_SizeChanged(object sender, EventArgs e)
{
m_rectWorking = new Rectangle(this.Width / 2 - this.Width / 8, this.Width / 4, this.Width / 4, this.Height - this.Width / 2);
m_rectLeft = new Rectangle(this.Width / 2 - this.Width / 8, m_rectWorking.Top + m_rectWorking.Width / 2, (this.Width - this.Width / 4) / 2 - 2, m_rectWorking.Height - m_rectWorking.Width * 2);
}
/// <summary>
/// 画温度计
/// </summary>
/// <param name="e"></param>
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
var g = e.Graphics;
g.SmoothingMode = SmoothingMode.HighQuality;
//玻璃管
GraphicsPath path = new GraphicsPath();
path.AddLine(m_rectWorking.Left, m_rectWorking.Bottom, m_rectWorking.Left, m_rectWorking.Top + m_rectWorking.Width / 2);
path.AddArc(new Rectangle(m_rectWorking.Left, m_rectWorking.Top, m_rectWorking.Width, m_rectWorking.Width), 180, 180);
path.AddLine(m_rectWorking.Right, m_rectWorking.Top + m_rectWorking.Width / 2, m_rectWorking.Right, m_rectWorking.Bottom);
path.CloseAllFigures();
g.FillPath(new SolidBrush(glassTubeColor), path);
//底部
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);
g.FillEllipse(new SolidBrush(glassTubeColor), rectDi);
g.FillEllipse(new SolidBrush(mercuryColor), new Rectangle(rectDi.Left + 4, rectDi.Top + 4, rectDi.Width - 8, rectDi.Height - 8));
//值
float fltHeightValue = (float)(Value / (maxValue - minValue) * m_rectLeft.Height);
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));
g.FillRectangle(new SolidBrush(mercuryColor), rectValue);
//
//刻度
decimal decSplit = (maxValue - minValue) / spCount;
decimal decSplitHeight = m_rectLeft.Height / spCount;
for (int i = 0; i <= spCount; i++)
{
g.DrawLine(new Pen(new SolidBrush(ForeColor), 1), new PointF(m_rectLeft.Left + 1, (float)(m_rectLeft.Bottom - decSplitHeight * i)), new PointF(m_rectLeft.Left + 8, (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 - sizeLeft.Width-2, m_rectLeft.Bottom - (float)decSplitHeight * i - 5));
if (i != spCount)
{
if (decSplitHeight > 40)
{
var decSp1 = decSplitHeight / 10;
for (int j = 1; j < 10; j++)
{
if (j == 5)
{
g.DrawLine(new Pen(new SolidBrush(ForeColor), 1), new PointF(m_rectLeft.Left + 1, (m_rectLeft.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))), new PointF(m_rectLeft.Left + 8, (m_rectLeft.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))));
}
else
{
g.DrawLine(new Pen(new SolidBrush(ForeColor), 1), new PointF(m_rectLeft.Left + 1, (m_rectLeft.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))), new PointF(m_rectLeft.Left + 5, (m_rectLeft.Bottom - (float)decSplitHeight * i - ((float)decSp1 * j))));
}
}
}
else if (decSplitHeight > 10)
{
g.DrawLine(new Pen(new SolidBrush(ForeColor), 1), new PointF(m_rectLeft.Left + 1, (m_rectLeft.Bottom - (float)decSplitHeight * i - (float)decSplitHeight / 2)), new PointF(m_rectLeft.Left + 5, (m_rectLeft.Bottom - (float)decSplitHeight * i - (float)decSplitHeight / 2)));
}
}
}
//单位
string strLeftUnit = GetUnitChar(leftTemperatureUnit);
g.DrawString(strLeftUnit, Font, new SolidBrush(ForeColor), new PointF(m_rectLeft.Left + 2, 5));
float bmaxValue = (float)(BMaxValue / (maxValue - minValue) * m_rectLeft.Height);
float bminValue = (float)(BMinValue / (maxValue - minValue) * m_rectLeft.Height);
//低温线
g.DrawLine(new Pen(new SolidBrush(Color.Blue), 1), m_rectWorking.Left + 2, m_rectLeft.Top + (m_rectLeft.Height - bminValue), m_rectWorking.Left + m_rectWorking.Width, m_rectLeft.Top + (m_rectLeft.Height - bminValue));
//高温线
g.DrawLine(new Pen(new SolidBrush(Color.Orange), 1), m_rectWorking.Left + 2, m_rectLeft.Top + (m_rectLeft.Height - bmaxValue), m_rectWorking.Left + m_rectWorking.Width, m_rectLeft.Top + (m_rectLeft.Height - bmaxValue));
var sizeValue = g.MeasureString(mValue.ToString("0.##"), ValueFont);
g.DrawString(mValue.ToString("0.##"), ValueFont, new SolidBrush(ValueColor), new PointF(rectDi.Left + (rectDi.Width - sizeValue.Width) / 2, rectDi.Top + (rectDi.Height - sizeValue.Height) / 2 + 1));
}
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;
}
}
partial class UThermometer
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region 组件设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.SuspendLayout();
//
// UThermometer
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Name = "UThermometer";
this.Size = new System.Drawing.Size(67, 230);
this.SizeChanged += new System.EventHandler(this.UThermometer_SizeChanged);
this.ResumeLayout(false);
}
#endregion
}