C#自定义事件(简单版本)
C#中的事件分为两种:一种是厂商微软在VS中已经内置,以供用户使用;另一种是有用户自己定义的事件;
先简单回顾下第一种:
【场景1】一个Form上一个Textbox控件和Button控件,当用户按下Button控件时,textbox显示内容“按钮被按下”,当用户松开按钮时,textbox则显示“按钮松开”;
代码如下:
using System.Windows.Forms; namespace ButtonEventBokeyuan { class Program { static void Main(string[] args) { MyForm1 myForm1 = new MyForm1(); myForm1.FormInitShow(); } } public class MyForm1 { Form form1 = new Form();//定义类的字段-控件1 Button button = new Button();//定义类的字段-控件2 TextBox textBox = new TextBox();//定义类的字段-控件3 public void FormInitShow() { button.Text = "Press me"; button.Top = 30; form1.Controls.Add(button); form1.Controls.Add(textBox); button.MouseDown += button_MouseDown;//VS中button自带的事件挂接事件处理器 button.MouseUp += button_MouseUp;//VS中button自带的事件挂接事件处理器 form1.ShowDialog(); } private void button_MouseUp(object sender, MouseEventArgs e) { this.textBox.Text = "按钮被松开"; } private void button_MouseDown(object sender, MouseEventArgs e) { this.textBox.Text = "按钮被按下"; } } }
运行效果:
以上回顾了VS自带的事件;
接下来,看看第二种,咱们自己如何定义一个类的事件内,以便让其他人去订阅,即事件的挂接;
【场景2】:现在有3种人,指挥官、士兵、平民,他们全部派生自人这个基类;人这个类都具有Run()这个可重写的方法;
现在指挥官有个事件——咳嗽(暗号),而士兵订阅了这个咳嗽事件,一旦指挥官走出来,然后咳嗽,士兵就会立即发起进攻;同时士兵也有进攻开始这个事件,该事件被平民订阅,一旦士兵发起进攻,平民就会跑;
先看类图:
接下来实现完整代码:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace CustomerEvent { public delegate void UserRequest(); class Program { static void Main(string[] args) { Commander commander = new Commander("Jack"); Soldier soldier = new Soldier("Herry"); Civilian civilian = new Civilian("Allen"); commander.KekeEvent += soldier.OnKekeHandler;//指挥官的咳嗽暗号事件订阅 soldier.AttackBegin += civilian.OnAttackingHandler;//士兵的开始攻击事件订阅 commander.Trigger();//指挥动作引起一些列士兵和平民的事件; Console.ReadLine(); } } /// <summary> /// 基类 /// </summary> public class Person { private string name; public Person(string name) { this.name = name; } public string Name { get; set; } public virtual void OnAttackingHandler() { Console.WriteLine($"{GetTime.GetTimeNow()}{this.Name}开始跑了。。。"); } } /// <summary> /// 指挥官类,具有咳嗽的事件,暗号 /// </summary> class Commander : Person { public Commander(string name) : base(name) { this.Name = name; } public event UserRequest KekeEvent; public void Trigger() { this.OnAttackingHandler(); Console.WriteLine($"{GetTime.GetTimeNow()}指挥官{this.Name}咳嗽暗号");//指挥官跑出来发出咳嗽暗号 if (KekeEvent!=null)//事件不为空,则执行 { KekeEvent(); } else { Console.WriteLine($"{GetTime.GetTimeNow()}commander没触发事件"); } } public override void OnAttackingHandler() { Thread.Sleep(100); Console.WriteLine($"{GetTime.GetTimeNow()}指挥官{this.Name}跑出来"); } } /// <summary> /// 士兵类; /// </summary> class Soldier : Person { public event UserRequest AttackBegin; public Soldier(string str) : base(str) { this.Name = str; } internal void OnKekeHandler() { Thread.Sleep(100); Console.WriteLine($"{GetTime.GetTimeNow()}士兵{this.Name}开始攻击..."); if (AttackBegin != null) { AttackBegin(); } else { } } public override void OnAttackingHandler() { Thread.Sleep(20); Console.WriteLine($"{GetTime.GetTimeNow()}士兵{this.Name}开始跑了..."); } } /// <summary> /// 平民类 /// </summary> class Civilian : Person { public Civilian(string name) : base(name) { this.Name = name; } public override void OnAttackingHandler() { Thread.Sleep(100); Console.WriteLine($"{GetTime.GetTimeNow()}平民{this.Name}逃难跑了。。。"); } } class GetTime { public static string GetTimeNow() { return DateTime.Now.ToString("hh:mm:ss.fff")+">>"; } } }
实现效果:
End.
写在最后,文章中的第二个场景是本人原创Demo,用来更好地理解用户事件的编程技术;重在自己多练习,不然觉得自己懂了,一旦动手,仍然两眼一抹黑!
#未经本人允许,禁止各种形式转载与转发#
谢谢!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?