Winform自定义控件 —— 指示灯

2023-11-05

        在开始阅读本文之前,如果您有学习创建自定义控件库并在其他项目中引用的需求,请参考:在Visual Studio中创建自定义Winform控件库并在其他解决方案中引用https://blog.csdn.net/YMGogre/article/details/126508042


目录

1、应用场景: 

1.1、本文的应用场景: 

2、所需资源: 

3、源代码: 

4、使用方法: 

5、效果演示:


1、应用场景: 

  • 当我们需要在窗口上通过一个指示灯来表示一个硬件设备或者程序的运行状态时;
  • 当我们需要一个可以显示不同颜色的指示灯来表征硬件设备或程序不同的状态时;
  • 当我们需要指示灯可以对用户的"点击"之类的交互做出响应时; 

1.1、本文的应用场景: 

        此控件设计初衷是:采用一个四色指示灯来表示某件事情的执行状态。共设置有四个状态:"waiting(等待中)"、"underway(正在进行)"、"completed(已完成)"、"pick(选中)"。分别通过四种颜色来表征:"DimGray(暗灰色)"、"Cornsilk(玉米丝色)"、"Aquamarine(碧绿色)"、"Coral(珊瑚色)"。

        此外,如果我们对某些"已完成"的事件不满意,我们可以选中那些事件对应的指示灯,以方便程序对我们选中的事件做后续操作:

        我们可以通过鼠标点击选中"已完成"状态下的指示灯,此时指示灯状态会改为"选中",当然也可以取消选中;而其他状态下的指示灯无法被选中。 

2、所需资源: 

(无) 

3、源代码: 

/* IndicatorLight.cs */

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

//注意命名空间修改为自己项目的命名空间
namespace WindowsFormsControlLibraryMadeByXJY
{
    public partial class IndicatorLight : UserControl
    {
        private bool _Light_clickable = true;
        private string _Light_text = "";
        private int Curr_StatusCode;        //当前状态编码
        private enum Light_States
        {
            waiting = 0,
            underway,
            completed,
            pick
        }
        private string[] Get_Status = new string[] { "waiting", "underway", "completed", "pick" };

        private Color Curr_Color;           //当前颜色
        private Color[] lightColors = new Color[] {Color.DimGray, Color.Cornsilk, Color.Aquamarine, Color.Coral};


        /// <summary>
        /// 自定义的text属性
        /// </summary>
        [Category("Text"), Description("文本框里的提示文字"), Browsable(true)]
        public string Light_text
        {
            get { return _Light_text; }
            set
            {
                if (value == null) throw new ArgumentNullException("value");

                _Light_text = value;
                this.Invalidate();
            }
        }

        /// <summary>
        /// 设置指示灯是否可以被点击,这取决于你是否想要指示灯对用户交互作出反应
        /// </summary>
        public bool Light_clickable
        {
            get { return _Light_clickable; }
            set
            {
                _Light_clickable = value;
            }
        }

        /// <summary>
        /// 设置四色灯状态,暗灰色表示"等待中";玉米丝色表示"进行中";碧绿色表示"已完成";珊瑚色表示"选中"
        /// 可以自行添加更多的case来给指示灯添加更多的颜色以及这些颜色对应的状态;
        /// 这需要你:1、在Light_States添加你想使用指示灯来表示的状态项;
        ///           2、在Get_Status中同样添加你想使用指示灯来表示的状态项;
        ///           3、在lightColors中添加你想用于表征该状态的颜色。
        /// </summary>
        /// <param name="s">状态:"waiting"表示"等待中";"underway"表示"进行中";"completed"表示"已完成";"pick"表示"选中";以上都不是则默认进入"waiting"状态</param>
        public void SetStatus(string s)
        {
            switch (s)
            {
                case "waiting":
                    Curr_StatusCode = (int)Light_States.waiting;
                    break;
                case "underway":
                    Curr_StatusCode = (int)Light_States.underway;
                    break;
                case "completed":
                    Curr_StatusCode = (int)Light_States.completed;
                    break;
                case "pick":
                    Curr_StatusCode = (int)Light_States.pick;
                    break;
                default:        //对于其他输入均默认进入"等待中"状态
                    Curr_StatusCode = (int)Light_States.waiting;
                    break;
            }
            try
            {
                Curr_Color = lightColors[Curr_StatusCode];
                this.Invalidate();
            }
            catch(Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }

        /// <summary>
        /// 获取信号灯状态,根据当前状态返回对应的字符串(比如当前状态为"waiting",则返回"waiting")
        /// </summary>
        public string GetStatus
        {
            get { return Get_Status[Curr_StatusCode]; }
        }

        /// <summary>
        /// 重置信号灯状态为"waiting"
        /// </summary>
        public void ResetState()
        {
            this.SetStatus("waiting");
        }

        public IndicatorLight()
        {
            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.Cursor = Cursors.Hand;   
            this.Size = new Size(50, 50);
            Curr_StatusCode = (int)Light_States.waiting;
            Curr_Color = lightColors[Curr_StatusCode];
        }

        /// <summary>
        /// 重绘控件
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            Graphics g = e.Graphics;
            g.SmoothingMode = SmoothingMode.AntiAlias;
            g.DrawEllipse(new Pen(new SolidBrush(Color.Blue),2), new Rectangle(4, 4, this.Width - 8, this.Height - 8));
            g.FillEllipse(new SolidBrush(Curr_Color), new Rectangle(4, 4, this.Width - 8, this.Height - 8));           
            TextRenderer.DrawText(g, Light_text, this.Font, new Rectangle(4, 4, this.Width - 8, this.Height - 8), SystemColors.InfoText);
        }


        /// <summary>
        /// 处理四色灯控件的SizeChanged事件中针对只调整单边大小的情况。
        /// </summary>
        /// <param name="sender">事件的来源</param>
        /// <param name="e">The <see cref="EventArgs"/>包含事件数据的实例</param>
        void UCSignalLamp_SizeChanged(object sender, EventArgs e)
        {
            this.Height = this.Width;
        }



        /// <summary>
        /// 是否选中,当该控件状态为"已完成"时,点击该控件会将状态修改为"选中",当然再次点击可以取消选中。对于其他状态("等待中"、"进行中")则不做动作。
        /// 注意:当且仅当用户设置 Light_clickable = true 时该事件处理代码才会得到执行
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lightClick(object sender, EventArgs e)
        {
            if (_Light_clickable)
            {
                if (this.Curr_StatusCode == (int)Light_States.completed)
                {
                    this.SetStatus("pick");         //选中
                }
                else if(this.Curr_StatusCode == (int)Light_States.pick)
                {
                    this.SetStatus("completed");    //取消选中
                }
                else { }
            }
        }
    }
}
/* IndicatorLight.Designer.cs */

//注意命名空间修改为自己项目的命名空间
namespace WindowsFormsControlLibraryMadeByXJY
{
    partial class IndicatorLight
    {
        /// <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()
        {
            components = new System.ComponentModel.Container();
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.Click += new System.EventHandler(this.lightClick);
            this.SizeChanged += new System.EventHandler(this.UCSignalLamp_SizeChanged);
        }

        #endregion
    }
}

4、使用方法: 

  • 在代码中通过设置该类实例化对象的Cursor属性可以更改鼠标指针位于控件上时显示的光标;
    /* 假设我们有一个 IndicatorLight1 对象 */
    IndicatorLight1.Cursor = Cursors.Arrow;
    ...
    
  • 通过设置Light_clickable属性可以更改该控件是否可以被点击;
    IndicatorLight1.Light_clickable = false;
    IndicatorLight1.Light_clickable = true;
  • 通过调用SetStatus()方法可以修改指示灯的状态(外部表现为颜色发生改变);
    IndicatorLight1.SetStatus("underway");
    IndicatorLight1.SetStatus("completed");
    ...
  • 通过获取GetStatus属性可以使用指示灯状态做一些简单的判断操作;
    if (IndicatorLight1.GetStatus == "pick")
    {
        ...
    }

5、效果演示: 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Winform自定义控件 —— 指示灯 的相关文章

  • 汤博乐开发工具

    我想创建 Tumblr 主题 有趣的是有没有 IDE Netbeans Eclipse PHPStorm 插件或开发工具 理想的情况是在浏览器中预览我的主题 而不将其上传到 Tumblr 谢谢 我找到了自己的方法来使用 PhpStorm 或
  • 如何在 Eclipse 中启用列选择模式?

    News 写道 Eclipse 3 5 终于支持列选择 不幸的是我不知道如何启用它 我尝试按 ALT 键 就像我在 Visual Studio 和所有其他 Microsoft 产品中习惯的那样 但这没有效果 如何在 Eclipse 中标记垂
  • 在 Rstudio 上浏览 R 代码的高效递归方式?

    我正在使用 RStudio 我开始觉得有必要通过包代码来更深入地理解或破解某些功能 当我尝试使用导航时使用 Ctrl 单击鼠标 http www rstudio com ide docs using navigation对于包内定义的函数
  • 更改 Eclipse 启动配置中的默认“要运行的程序”

    我时不时地使用以下命令从 Eclipse 中启动 JUnit 测试 运行方式 gt JUnit 插件测试 默认情况下 Eclipse 假设您正在运行需要工作台的东西 并在启动配置的 Main 部分中进行选择 LaunchConfig gt
  • 为家庭作业选择 Java IDE [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 谁能推荐一个轻量级的 Java IDE 不需要您每次编译和运行程序时都创建新项目 我只想能够打开jav
  • 设置 xamarin studio 以与 PCL 和 MVVMCross 配合使用

    我真的很喜欢 Xamarin Studio 并且正在寻找一个模板解决方案来开始使用 MvvmCross 开发跨设备应用程序 但我找不到如何将项目设置为与 Xamarin Studio 一起使用 PCL 和 MvvmCross 如果有人能给我
  • 设置 eclipse 进行 Windows 驱动程序开发

    我正在尝试使用 WDK 7 1 0 编写用户模式 Windows XP Vista 和 7 虚拟打印机驱动程序 我打算使用 eclipse IDE 进行开发 所以想知道是否可以进行相同的设置 我希望做以下事情 1 Eclipse 能够识别
  • Visual Studio Professional 2013 Update 5 中的“在线服务不可用”问题

    我一直在 vscode 2013 工作直到今天 但是 当我今天早上尝试打开 IDE 时 它收到 您的许可证已过时 必须更新 错误消息 如下所示 在我尝试更新许可证和登录操作之后 当我尝试这两个时 它得到 在线服务不可用 请稍后重试 错误消息
  • Netbeans 版本控制文件颜色代码?

    我试图找到一个图例来帮助解释 NetBeans 用于描述文件状态的不同颜色 我的一些文件颜色是 Grey Blue Green 还有其他我还没有发现的 如果有帮助 我将使用带有 CVS 的 Netbeans 6 7 这些颜色是什么 绿色意味
  • emacs 的最佳 java 工具 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • VBA:新集合 -> 模块不是有效类型

    我尝试使用集合作为函数的一部分 但是在编译时不断收到错误 模块不是有效类型 即使该函数只是定义一个集合 我也会得到相同的结果 Function CountUniqueTags Dim table As Collection Set tabl
  • Visual Studio IDE 中功能后的空间

    如何设置 Visual Studio 中的设计以在我的 javascript 函数后面放置一个空格 目前 当我按下返回键时 我得到了这个 var myfunc function 当我想要这个的时候 var myfunc function 知
  • Eclipse 中选定单词的括号

    几天前 我觉得这个问题很愚蠢 所以不要将其发布在这里 但即使在搜索了很多之后 我也没有找到合适的解决方案 对于那些使用过的人TextEdit 在 Mac 上 他们会完全知道我在说什么 在编码时 我只想在单词或一行上加上引号或括号 为此 我必
  • Spyder 未检测到导入的 python 文件中的更改

    我正在使用 Spyder 3 2 4 Python 3 6 Spyder 不会检测导入的 python 文件中的更改 例如 测试2 py def func return 5 测试1 py import test2 a test2 func
  • 在 Eclipse 中隐藏重复的工具栏项

    我不知道如何 但我的 STS 有重复的工具栏项目 我不知道如何删除它们 这是我复制的工具栏的样子 我想摆脱这些 我试图隐藏工具栏 但这没有帮助 有人知道如何删除重复的吗 自从升级到 Oxygen 以来 我一直遇到同样的问题 我无法可靠地重现
  • Sublime Text 缩进设置被文件覆盖

    我正在开发一个项目 其中制表符大小应该为 4 并且制表符不应该是空格 我更新了我的 Preferences sublime settings 文件以包括 detect indentation false tab size 4 transla
  • 如何折叠 C# 中的所有 #region 和方法?

    全部一一崩掉真是太烦人了 Like Steve said CTRL M plus CTRL L for collapsing all regions recursively This one is a toggle meaning you
  • 如何在 PyCharm 社区版中运行 Django 项目的调试服务器?

    有人在 PyCharm 社区版中为 Django 项目设置调试配置时遇到问题吗 IDE 的社区版缺少项目设置中的项目类型选项 然后当我设置 调试 或 运行配置 时 它会要求我提供应该运行的脚本 Django 需要什么脚本 manage py
  • 是否可以配置CLion来独立编译项目中的源文件?

    我目前正在使用 JetBrains CLion IDE 用 C 语言进行一些 Project Euler 挑战 当我用 Python 和 Java 分别用 PyCharm 和 IntelliJ 完成这些任务时 我总是能够创建一个名为 Pro
  • 如何在不使用 IDE 的情况下在 Linux 上运行 Java 项目

    我是 Java 新手 基本上 我开发了一个java项目 其中包含Eclipse中的多个Java包 该项目在我安装了 redhat Linux 的桌面上运行正常 然而 我需要在一个更强大的没有安装X11的Linux服务器 redhat ent

随机推荐

  • perp系列之七:perp手册

    perp系列之七 perp手册 版本说明 版本 作者 日期 备注 0 1 ZY 2019 5 29 初稿 目录 文章目录 perp系列之七 perp手册 版本说明 目录 1 该发行版包括以下手册页 perp intro 8 perp set
  • 服务器端安装jupyter notebook并在本地使用与环境配置一条龙服务【服务器上跑ipynb】

    linux服务器端安装jupyter notebook并在本地使用 1 生成配置文件 2 配置Jupyter notebook密码 3 修改配置文件 jupyter jupyter notebook config py 4 本地访问远端的服
  • 微调Hugging Face中图像分类模型

    前言 本文主要针对Hugging Face平台中的图像分类模型 在自己数据集上进行微调 预训练模型为Google的vit base patch16 224模型 模型简介页面 代码运行于kaggle平台上 使用平台免费GPU 型号P100 笔
  • About the Storage allocation

    It doesn t matter what programming language u use it s all about the usage of variable storage management 1 Static Dynam
  • 刷爆力扣!反超对象第五天之最长公共前缀

    目录 1 题目解析 2 代码提交 3 知识点学习 1 题目解析 题目 编写一个函数来查找字符串数组中的最长公共前缀 如果不存在公共前缀 返回空字符串 示例 1 输入 strs flower flow flight 输出 fl 此题其实也很简
  • ant design pro中umi-request拦截请求统一处理报错提示

    ant design pro项目请求用的是umi request 对于请求不成功的情况需要给用户错误提示 但是每个请求都对错误情况做处理 冗余代码太多 所以在src utils request页面拦截请求统一处理 umi request 访
  • 数字电子技术基础大作业---电子表、流水灯

    数字电子技术基础大作业 电子表 流水灯 一 电子表 1 1应用的元件 555 六片74LS160N 三片74LS26D 两片74LS04D 六个个D HEX 十六进制输入的显示数码管 电阻 电容若干 1 2简单原理 用555定时器产生频率为
  • NLP中的余弦相似度 Cosine similarity 是什么,如何计算(学习心得)

    余弦相似度 Cosine similarity To measure how similar two words are we need a way to measure the degree of similarity between t
  • mysql支持copymanage方式么_PostgreSQL:Java使用CopyManager实现客户端文件COPY导入

    在MySQL中 可以使用LOAD DATA INFILE和LOAD DATA LOCAL INFILE两种方式导入文本文件中的数据到数据库表中 速度非常快 其中LOAD DATA INFILE使用的文件要位于MySQL所在服务器上 LOAD
  • python安装sklearn_如何使用VScode引入python第三方模块

    pip 是 Python 包管理工具 该工具提供了对Python 包的查找 下载 安装 卸载的功能 通过pip引入第三方模块 如果已经安装了pip 直接进入第五步 比如我要引入cv2 1 打开vscode 2 打开终端 3 输入pip in
  • ROS GDB 使用和core dump分析

    参考 http wiki ros org roslaunch Tutorials Roslaunch 20Nodes 20in 20Valgrind 20or 20GDB https blog csdn net sunxiaoju arti
  • 实现领域驱动设计----第六章

    当你决定以恶搞领域概念是否是一个值对象时 你需要考虑他是否拥有以下特征 它度量或者描述了领域中的一件东西 它可以作为不变量 它将不同的相关的属性组合成一个概念整体 当度量和描述改变时 可以用另一个值对象予以替换 它可以和其他值对象进行相等性
  • 【SpringBoot】还不会SpringBoot项目模块分层?来这手把手教你

    文章目录 前言 缘由 本文阅读时长 主要目标 试用人群 快速链接 水图 正文 1 IDEA新建项目 2 创建子模块 dependencies 依赖层 重点 3 创建子模块 main 主启动层 重点 4 创建子模块 module 模块层 5
  • Eclipse关于搭建JSP运行环境(超级详细过程附带网页地址)

    1 下载jdk 2 配置环境变量 3 下载安装Tomcat 4 下载安装Eclipse 5 配置Eclipse运行第一个JSP程序 一 下载jdk 百度地址栏搜索https www oracle com java technologies
  • js替换字符串中的空格,换行符\r\n或\n替换成

    为了让回车换行符正确显示 需要将 n 或 r n 替换成 br 同样地 将空格替换存 nbsp 这里我们通过正则表达式来替换 一 替换所有的空格 回车换行符 原始字符串 var string 欢迎访问 r nhangge com 做最好的开
  • Linux_8_磁盘存储和文件系统

    1 磁盘结构 1 1 设备文件 一切皆文件 open read write close 设备文件 关联至一个设备驱动程序 进而能够跟与之对应硬件设备进行通信 设备号码 主设备号 major number 标识设备类型 次设备号 minor
  • A*寻路算法浅析

    最近刚接触A 寻路算法 听说是一种比较高效的自动寻路的算法 当然 事实也正是如此 这么好的东西 自然是要收入囊中的 说不定什么时候也能派上用场呢 为了学习这个 也是上网找了好多资料 看了好多博客 但是貌似有些关键点没有具体说明 所以自己也是
  • understand - 笔记

    术语 Terminology Architecture 层级 An architecture is a hierarchical aggregation of source code units entities An architectu
  • 用vb语言编写一个抄底的源代码程序实例

    以下是一个基于通达信软件编写的简单抄底源代码程序 用于自动识别股票的底部形态并发出买入信号 vbs 复制 导入通达信软件自带的股票数据接口 Dim TdxApi Set TdxApi CreateObject TdxApi TdxLocal
  • Winform自定义控件 —— 指示灯

    在开始阅读本文之前 如果您有学习创建自定义控件库并在其他项目中引用的需求 请参考 在Visual Studio中创建自定义Winform控件库并在其他解决方案中引用https blog csdn net YMGogre article de