Winform自定义控件 —— 指示灯

        在开始阅读本文之前,如果您有学习创建自定义控件库并在其他项目中引用的需求,请参考:在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、效果演示: 

 

  • 1
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值