C# Winform中制作精美控件(2)

仓库温度监控系统重有个控件,就是温度监控,还是比较精美的,那么我们来看看制作的要点有哪些。

前面我们讨论过布局和圆角按钮。这节主要关注温度计控件

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
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/735049.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用 Ubuntu x86_64 平台交叉编译适用于 Linux aarch64(arm64) 平台的 QT5(包含OpenGL支持) 库

使用 Ubuntu AMD64 平台交叉编译适用于 Linux ARM64 平台的 QT5(包含 OpenGL/WebEngine 支持) 库 目录 使用 Ubuntu AMD64 平台交叉编译适用于 Linux ARM64 平台的 QT5(包含 OpenGL/WebEngine 支持) 库写在前面前期准备编译全流程1. 环境搭建2. 复制源码包并解压&#xff0c;创…

【单片机毕业设计选题24024】-房间自动除湿控制系统

系统功能: 系统分为手动和自动模式&#xff0c;上电默认为自动模式。自动模式下如果获取到湿度 值大于设定的湿度值则自动打开风扇&#xff0c;手动模式下手动开关风扇。 系统上电后显示“欢迎使用除湿控制系统请稍后”&#xff0c;两秒钟后进入主页面显示。 第一行显示系统…

[FreeRTOS 功能应用] 互斥访问与回环队列 功能应用

文章目录 一、基础知识点二、代码讲解三、结果演示四、代码下载 一、基础知识点 [FreeRTOS 基础知识] 互斥访问与回环队列 概念 [FreeRTOS 内部实现] 互斥访问与回环队列 [FreeRTOS 内部实现] 创建任务 xTaskCreate函数解析 本实验是基于STM32F103开发移植FreeRTOS实时操作系…

A bug‘s life 虫子的生活(带权并查集)

题目链接: 2492 -- A Bugs Life (poj.org) 题目描述: 思路: 带权并查集&#xff0c;处理方法基本与食物链(http://t.csdnimg.cn/fSnRr)相同&#xff0c;没什么思维创新 但是一开始WA了几次&#xff0c;有些细节没有注意好&#xff0c;还是需要静下心来&#xff0c;好好分析问…

LabVIEW程序闪退问题

LabVIEW程序出现闪退问题可能源于多个方面&#xff0c;包括软件兼容性、内存管理、代码质量、硬件兼容性和环境因素。本文将从这些角度进行详细分析&#xff0c;探讨可能的原因和解决方案&#xff0c;并提供预防措施&#xff0c;以帮助用户避免和解决LabVIEW程序闪退的问题。 1…

数据结构与算法笔记:基础篇 - 初始动态规划:如何巧妙解决“双十一”购物时的凑单问题?

概述 淘宝的 “双十一” 购物节有各种促销活动&#xff0c;比如 “满 200 元减 50元”。假设你女朋友购物车中有 n 个&#xff08;n > 100&#xff09;想买的商品&#xff0c;它希望从里面选几个&#xff0c;在凑够满减条件的前提下&#xff0c;让选出来的商品价格总和最长…

汉语拼音字母表 (声母表和韵母表)

汉语拼音字母表 [声母表和韵母表] 1. 汉语拼音声母表2. 汉语拼音韵母表References 1. 汉语拼音声母表 声母是韵母前的辅音&#xff0c;与韵母一起构成一个完整的音节。 辅音是发声时&#xff0c;气流在口腔中受到各种阻碍所产生的声音&#xff0c;发音的过程即是气流受阻和克…

Flink-03 Flink Java 3分钟上手 Stream 给 Flink-02 DataStreamSource Socket写一个测试的工具!

代码仓库 会同步代码到 GitHub https://github.com/turbo-duck/flink-demo 当前章节 继续上一节的内容&#xff1a;https://blog.csdn.net/w776341482/article/details/139875037 上一节中&#xff0c;我们需要使用 nc 或者 telnet 等工具来模拟 Socket 流。这节我们写一个 …

【python】linux下安装chromedriver

首先&#xff0c;安装selenium模块 pip3 install selenium查看系统内chrome版本&#xff1a; google-chrome --version 根据谷歌浏览器版本下载对应的浏览器驱动版本&#xff1a; wget https://storage.googleapis.com/chrome-for-testing-public/126.0.6478.114/linux64/ch…

2024年6月大众点评成都餐饮店铺POI分析22万家

2024年6月大众点评成都餐饮店铺POI共有221002家 店铺POI点位示例&#xff1a; 店铺id CACuqlcUQApLA7Ki 店铺名称 峨眉山豆腐脑(百吉街店) 十分制服务评分 7.3 十分制环境评分 7.5 十分制划算评分 7.1 人均价格 18 评价数量 38 店铺地址 百吉街86号1层 大类 美食 中类…

Day7 —— 大数据技术之Hive

Hive快速入门系列 Hive的概述什么是Hive&#xff1f;使用Hive的原因 Hive架构Hive安装Hive配置文件修改启动Hive以命令行方式启动&#xff08;在$HIVE_HOME/bin目录下&#xff09;以JDBC连接启动&#xff08;beeline方式连接&#xff09; Hive基本操作Hive数据库操作Hive表操作…

天气冷电脑不能启动找不到硬盘

https://diy.zol.com.cn/2004/0611/101994.shtml

为什么 JakeWharton 建议:App 只要用到一个 Activity ?

我们来看看这条回答都提到了哪些内容&#xff0c;对 Activity 和 Fragment 之间的爱恨情仇有何独到的见解&#xff0c;凭什么能得到 JakeWharton 本尊的青睐有加。 因为 Activity 是一个程序入口。你可以将其视为 app 的一个 main 函数。站在用户的立场上&#xff0c;通常你进入…

ARM功耗管理软件之WFIWFE

安全之安全(security)博客目录导读 思考&#xff1a;功耗管理软件栈及示例&#xff1f;WFI&WFE&#xff1f;时钟&电源树&#xff1f;DVFS&AVS&#xff1f; ARM功耗管理精讲与实战汇总参见&#xff1a;Arm功耗管理精讲与实战

IO模型详解

阻塞IO模型 假设应用程序的进程发起IO调用&#xff0c;但是如果内核的数据还没准备好的话&#xff0c;那应用程序进程就一直在阻塞等待&#xff0c;一直等到内核数据准备好了&#xff0c;从内核拷贝到用户空间&#xff0c;才返回成功提示&#xff0c;此次IO操作&#xff0c;称…

OkHttp框架源码深度剖析【Android热门框架分析第一弹】

OkHttp介绍 OkHttp是当下Android使用最频繁的网络请求框架&#xff0c;由Square公司开源。Google在Android4.4以后开始将源码中的HttpURLConnection底层实现替换为OKHttp&#xff0c;同时现在流行的Retrofit框架底层同样是使用OKHttp的。 源码传送门 优点: 支持Http1、Http…

基于Java的农机电招平台系统

你好呀&#xff0c;我是计算机学姐码农小野&#xff01;如果你对农机电招平台系统感兴趣或有相关开发需求&#xff0c;可以私信联系我。 开发语言 Java 数据库 MySQL 技术 B/S结构&#xff0c;SpringBoot框架 工具 Eclipse&#xff0c;Navicat&#xff0c;Tomcat8.0 系…

24年下半年各省自考报名时间汇总

24年下半年各省自考报名时间汇总

C语言 | Leetcode C语言题解之第174题地下城游戏

题目&#xff1a; 题解&#xff1a; int calculateMinimumHP(int** dungeon, int dungeonSize, int* dungeonColSize) {int n dungeonSize, m dungeonColSize[0];int dp[n 1][m 1];memset(dp, 0x3f, sizeof(dp));dp[n][m - 1] dp[n - 1][m] 1;for (int i n - 1; i >…

利用JAVA语言调用GLM-4接口实战指南

一、什么是API接口 API&#xff08;Application Programming Interface&#xff0c;应用程序编程接口&#xff09;是一种软件接口&#xff0c;它定义了不同应用程序之间如何相互通信、交互。API接口分为很多种&#xff0c;常见的有Web API&#xff0c;数据库API&#xff0c;操…