在开始阅读本文之前,如果您有学习创建自定义控件库并在其他项目中引用的需求,请参考:在Visual Studio中创建自定义Winform控件库并在其他解决方案中引用https://blog.csdn.net/YMGogre/article/details/126508042
目录
1、应用场景:
1.1、本文的应用场景:
2、所需资源:
3、源代码:
4、使用方法:
5、效果演示:
此控件设计初衷是:采用一个四色指示灯来表示某件事情的执行状态。共设置有四个状态:"waiting(等待中)"、"underway(正在进行)"、"completed(已完成)"、"pick(选中)"。分别通过四种颜色来表征:"DimGray(暗灰色)"、"Cornsilk(玉米丝色)"、"Aquamarine(碧绿色)"、"Coral(珊瑚色)"。
此外,如果我们对某些"已完成"的事件不满意,我们可以选中那些事件对应的指示灯,以方便程序对我们选中的事件做后续操作:
我们可以通过鼠标点击选中"已完成"状态下的指示灯,此时指示灯状态会改为"选中",当然也可以取消选中;而其他状态下的指示灯无法被选中。
(无)
/* 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};
///
/// 自定义的text属性
///
[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();
}
}
///
/// 设置指示灯是否可以被点击,这取决于你是否想要指示灯对用户交互作出反应
///
public bool Light_clickable
{
get { return _Light_clickable; }
set
{
_Light_clickable = value;
}
}
///
/// 设置四色灯状态,暗灰色表示"等待中";玉米丝色表示"进行中";碧绿色表示"已完成";珊瑚色表示"选中"
/// 可以自行添加更多的case来给指示灯添加更多的颜色以及这些颜色对应的状态;
/// 这需要你:1、在Light_States添加你想使用指示灯来表示的状态项;
/// 2、在Get_Status中同样添加你想使用指示灯来表示的状态项;
/// 3、在lightColors中添加你想用于表征该状态的颜色。
///
/// 状态:"waiting"表示"等待中";"underway"表示"进行中";"completed"表示"已完成";"pick"表示"选中";以上都不是则默认进入"waiting"状态
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);
}
}
///
/// 获取信号灯状态,根据当前状态返回对应的字符串(比如当前状态为"waiting",则返回"waiting")
///
public string GetStatus
{
get { return Get_Status[Curr_StatusCode]; }
}
///
/// 重置信号灯状态为"waiting"
///
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];
}
///
/// 重绘控件
///
///
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);
}
///
/// 处理四色灯控件的SizeChanged事件中针对只调整单边大小的情况。
///
/// 事件的来源
/// The 包含事件数据的实例
void UCSignalLamp_SizeChanged(object sender, EventArgs e)
{
this.Height = this.Width;
}
///
/// 是否选中,当该控件状态为"已完成"时,点击该控件会将状态修改为"选中",当然再次点击可以取消选中。对于其他状态("等待中"、"进行中")则不做动作。
/// 注意:当且仅当用户设置 Light_clickable = true 时该事件处理代码才会得到执行
///
///
///
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
{
///
/// 必需的设计器变量。
///
private System.ComponentModel.IContainer components = null;
///
/// 清理所有正在使用的资源。
///
/// 如果应释放托管资源,为 true;否则为 false。
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region 组件设计器生成的代码
///
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
///
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
}
}
/* 假设我们有一个 IndicatorLight1 对象 */
IndicatorLight1.Cursor = Cursors.Arrow;
...
IndicatorLight1.Light_clickable = false;
IndicatorLight1.Light_clickable = true;
IndicatorLight1.SetStatus("underway");
IndicatorLight1.SetStatus("completed");
...
if (IndicatorLight1.GetStatus == "pick")
{
...
}