C#_event_事件
//-------------------事件---------------------------
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace _01事件理解 8 { 9 class Program 10 { 11 static void Main(string[] args) 12 { 13 Mp3Player mp3 = new Mp3Player(); 14 15 mp3.AfterPowerOn += ShowOn; 16 mp3.BeforePowerOff += ShowOff; 17 18 mp3.PowerOn(); 19 mp3.PowerOff(); 20 Console.ReadKey(); 21 } 22 23 24 static void ShowOn() 25 { 26 Console.WriteLine("播放开机动画"); 27 } 28 29 static void ShowOff() 30 { 31 Console.WriteLine("播放关机动画"); 32 } 33 34 } 35 36 37 38 39 public class Mp3Player 40 { 41 42 //将委托前面 添加event 变成事件 那么 该委托只能在该类内部实现 43 //在类的外部不能调用该委托 44 45 //也就是 外部只能注册或删除已经注册的方法 不能自己去调用 46 //调用只能是在这个类的内部 47 48 //也就是委托添加event之后 再类的外部 就变成了 event 只能通过+= -= 来注册 删除方法不能 加()执行 49 50 public event Action AfterPowerOn; 51 public event Action BeforePowerOff; 52 53 public void PowerOn() 54 { 55 56 Console.WriteLine("开机..."); 57 58 //开机后执行委托 可以理解为事件 59 if (AfterPowerOn != null) 60 { 61 AfterPowerOn(); 62 } 63 64 MusicStart(); 65 } 66 67 public void PowerOff() 68 { 69 70 MusicStop(); 71 72 //关机前的委托调用 如果委托不为空的话 此处理解为 事件 73 if (BeforePowerOff != null) 74 { 75 BeforePowerOff(); 76 } 77 Console.WriteLine("关机"); 78 79 } 80 81 private void MusicStart() 82 { 83 Console.WriteLine("开始播放music"); 84 } 85 86 private void MusicStop() 87 { 88 Console.WriteLine("Music stop..."); 89 } 90 } 91 }
//--------------------自定义控件 - 委托案例------
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Drawing; 5 using System.Data; 6 using System.Linq; 7 using System.Text; 8 using System.Threading.Tasks; 9 using System.Windows.Forms; 10 11 namespace _04委托案例2_LogIn 12 { 13 public partial class UILogIn : UserControl 14 { 15 public UILogIn() 16 { 17 InitializeComponent(); 18 } 19 public event UserLogInValidate userLogIn; 20 //(object sender,EventArgs e) 这里事件中参数 sender 代表是谁触发该事件 e 代表触发该事件的参数 21 private void button1_Click(object sender, EventArgs e) 22 { 23 //1.收集信息 24 string userNameInput = textBox1.Text.Trim(); 25 string userPassWord = textBox2.Text.Trim(); 26 //传入函数的参数 这里的LogInEventArgs是自定义的类型 主要用来传递要用到的参数 27 LogInEventArgs args = new LogInEventArgs(); 28 args.UserName = userNameInput; 29 args.UserPwd = userPassWord; 30 args.IsValidateOK = false; 31 32 if (userLogIn != null) 33 { 34 //2.传入参数验证 35 userLogIn(this, args); 36 //3.根据验证结果来做提示 37 if (args.IsValidateOK) 38 { 39 this.BackColor = Color.Green; 40 } 41 else 42 { 43 this.BackColor = Color.Red; 44 } 45 } 46 47 } 48 } 49 50 //自定义委托(事件触发者,自定义登录参数) 51 public delegate void UserLogInValidate(object sender,LogInEventArgs e); 52 }
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace _04委托案例2_LogIn 7 { 8 public class LogInEventArgs 9 { 10 private string _userName; 11 12 public string UserName 13 { 14 get { return _userName; } 15 set { _userName = value; } 16 } 17 18 private string _userPwd; 19 20 public string UserPwd 21 { 22 get { return _userPwd; } 23 set { _userPwd = value; } 24 } 25 26 private bool _isValidateOK; 27 28 public bool IsValidateOK 29 { 30 get { return _isValidateOK; } 31 set { _isValidateOK = value; } 32 } 33 34 35 } 36 }
//--------------------利用事件实现登录验证 和 利用接口来实现登录验证的对比----------
---在开始之前,我们来添加一个用户自定义控件,叫UCLogInValidate.cs 类似这样的:
点击登录按钮 编辑其click事件:
1 //声明事件 本质就是将此委托私有,然后公有出两个方法 += -= 2 public event Func<string, string, bool> LogInValidate; 3 private void button1_Click(object sender, EventArgs e) 4 { 5 string userName = textBox1.Text.Trim(); 6 string userPassword = textBox2.Text.Trim(); 7 if (LogInValidate != null) 8 { 9 bool bo=LogInValidate(userName, userPassword); 10 if (bo) 11 { 12 this.BackColor = Color.Green; 13 } 14 else { 15 this.BackColor = Color.Red; 16 } 17 } 18 }
这里使用了系统自带的Func委托 带这么多参数看着很挫 稍后我们再使用Action ,这里先用着 和接口对比下
//自定义控件修改之后 记得重新生成
对于暴露的LogInValidate 我们在Form1加载时赋值方法:
1 private void ucLogIn1_Load(object sender, EventArgs e) 2 { 3 ucLogIn1.LogInValidate += ucLogIn1_LogInValidate; 4 } 5 6 7 bool ucLogIn1_LogInValidate(string arg1, string arg2) 8 { 9 return (arg1 == "cheng" && arg2 == "123") ? true : false; 10 }
好吧我知道这个验证好搓。。
注册好方法后点击自定义的控件中的登录就可以验证了。
下面我们来看看用接口来实现:
//----使用接口来实现登录
添加用户自定义控件 同上
在自定义控件中 编写 登录方法:
1 //定义接口 2 public ILogInValidateable _iUserValidate; 3 4 private void button1_Click(object sender, EventArgs e) 5 { 6 //1.收集信息 7 MyEventArgs arg = new MyEventArgs(); 8 arg.IsValidateOK = false; 9 arg.UserName = textBox1.Text.Trim(); 10 arg.UserPassword = textBox2.Text.Trim(); 11 12 //2.调用接口验证 13 _iUserValidate.UserValidate(this, arg); //通过对接口赋值 (实现该接口的子类对象) 调用的就是子类对象的方法 14 15 if (arg.IsValidateOK) 16 { 17 this.BackColor = Color.Green; 18 } 19 else 20 { 21 this.BackColor = Color.Red; 22 } 23 }
这里就没再使用 event,定义了一个ILogInValidateable接口变量, 其声明如下:
1 public interface ILogInValidateable 2 { 3 void UserValidate(object sender, MyEventArgs e); 4 }
//注意接口定义 接口中方法前不能加修饰符 默认 隐式公开
也定义了MyEventArgs类型 用来传递参数 ,其声明如下 :(也可以使其继承自EventArgs)
1 /// <summary> 2 /// 为了传递参数而设计的类 3 /// </summary> 4 public class MyEventArgs 5 { 6 private bool _isValidateOK; 7 8 public bool IsValidateOK 9 { 10 get { return _isValidateOK; } 11 set { _isValidateOK = value; } 12 } 13 14 15 private string _userName; 16 17 public string UserName 18 { 19 get { return _userName; } 20 set { _userName = value; } 21 } 22 23 private string _userPassword; 24 25 public string UserPassword 26 { 27 get { return _userPassword; } 28 set { _userPassword = value; } 29 } 30 31 }
然后拖拽此控件 在Form登录时 注册方法:
1 private void ucLogInValidate1_Load(object sender, EventArgs e) 2 { 3 ucLogInValidate1._iUserValidate = new Validating(); 4 }
因为_iUserValidate是接口类型 赋值是 实现该接口的子类型对象: Validating声明如下:
1 public class Validating : ILogInValidateable 2 { 3 public void UserValidate(object sender, MyEventArgs e) 4 { 5 if (e.UserName == "Xuqingchi" && e.UserPassword == "HHHHH") 6 { 7 e.IsValidateOK = true; 8 } 9 else 10 { 11 e.IsValidateOK = false; 12 } 13 } 14 }
好吧,这验证也很搓,无视之^_~..
接下来验证就可以了:
什么?弱智的验证?
Never mind~
//Func参数太多?使用Action实现方法 就如上 传递自定义参数
public event Action<object sender,MyEventArgs e> _userValidate;
噢了~