事件Event的解释

能够发生什么事情,用于对象或者类之间的动作协调与信息传递。

发生——响应中的5个动作

  1. 我有一个事件A
  2. 一个人或者一群人关系我这个事件
  3. 我这个事件发生了
  4. 关心我这个事件的人会被依次通知到
  5. 被通知到的人拿到事件信息(又称“事件数据”“事件参数”“通知”)对事件进行响应,这叫处理事件

使用场景

一般多用于左面,手机等开发的客户端,因为这些程序经常是用户通过事件来驱动的,winform开发里面的控件,按钮啊,下拉框啊,单选框等控件,都有很多事件,点击,选择,双击,改变等。用户通过这个事件来响应不同的代码。

联动解释
点击button按钮,执行A方法,在A方法里面可以获取这个点击事件的一些信息,进行处理。
这句话解释成上面的发生——响应就是

  1. button有一个事件click
  2. A方法关注了button的click事件,或许可以再来几个方法,点击button执行ABCD方法也可以
  3. 点击了button后,click事件就发生了
  4. A方法被通知到了,执行了A方法
  5. A方法可以拿到这个 click事件的信息,进行处理,也可以不处理

    事件的五个部分

  6. 事件的拥有者

  7. 事件
  8. 事件响应者
  9. 事件处理器
  10. 事件订阅

    事件的使用

    关于事件参数: object sender:是事件的拥有者 EventArgs e:事件参数

简单例子1

  1. class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. //timer是事件的拥有者
  6. Timer timer = new Timer();
  7. timer.Interval = 1000;
  8. //事件的订阅者
  9. A a = new A();
  10. B b = new B();
  11. //A.Action是事件处理器,timer.Elapsed是每隔一段时间内执行一次的事件
  12. //用+=符号把两个绑在一起
  13. //A.Action的简便方法,硬写完后IDE自动提醒你生成这个方法
  14. //Action名字随意,可以叫其他的
  15. timer.Elapsed += a.Action;
  16. timer.Elapsed += b.Action;
  17. timer.Start();
  18. Console.ReadLine();
  19. }
  20. }
  21. class A
  22. {
  23. internal void Action(object sender, ElapsedEventArgs e)
  24. {
  25. Console.WriteLine("A执行了一次");
  26. }
  27. }
  28. class B
  29. {
  30. internal void Action(object sender, ElapsedEventArgs e)
  31. {
  32. Console.WriteLine("B执行了一次");
  33. }
  34. }

简单例子2

  1. static class Program
  2. {
  3. static void Main()
  4. {
  5. //form:事件的拥有者
  6. //Click:事件
  7. //a:事件的响应者
  8. //FormClicked:事件的处理器
  9. //this.form.Click += this.FormClicked;:事件订阅
  10. Form form = new Form();
  11. A a = new A(form);
  12. form.ShowDialog();
  13. }
  14. }
  15. class A
  16. {
  17. private Form form;
  18. public A(Form form)
  19. {
  20. if (form != null)
  21. {
  22. this.form = form;
  23. this.form.Click += this.FormClicked;
  24. }
  25. }
  26. private void FormClicked(object sender, EventArgs e)
  27. {
  28. this.form.Text = DateTime.Now.ToString();
  29. }
  30. }

自定义事件

完整声明例子

  1. class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. //一个顾客,一个服务员
  6. Customer customer = new Customer();
  7. Waiter waiter = new Waiter();
  8. //事件订阅
  9. customer.Order += waiter.Action;
  10. //现在顾客开始点菜,点菜事件完成后,客户过得账单就更新了
  11. customer.dian_cai();
  12. customer.PayTheBill();
  13. Console.ReadLine();
  14. }
  15. }
  16. //服务员相当于订阅者
  17. public class Waiter
  18. {
  19. public void Action(Customer customer, OrderEventArges e)
  20. {
  21. //订阅者可以通过事件传过来的参数获取事件信息
  22. Console.WriteLine("我给你上菜{0}",e.Cai_Name);
  23. //根据菜的大小,算钱
  24. double price = 10;
  25. switch (e.Size)
  26. {
  27. case "小":
  28. price = price * 0.5;
  29. break;
  30. case "大":
  31. price = price * 1.5;
  32. break;
  33. default:
  34. break;
  35. }
  36. //算完前给顾客加上
  37. customer.Bill += price;
  38. }
  39. }
  40. //一个客人类,里面有个方法,点菜了给账单付钱
  41. //顾客是事件拥有者,事件肯定在顾客里面啊,而且触发事件也在顾客内部触发
  42. public class Customer
  43. {
  44. private OrderEventHandler orderEventHandler;
  45. //声明一个事件,用OrderEventHandler委托类型来约束这个是事件
  46. //里面必须写两个东西,一个添加器add,一个移除器remove
  47. public event OrderEventHandler Order
  48. {
  49. add
  50. {
  51. this.orderEventHandler += value;
  52. }
  53. remove
  54. {
  55. this.orderEventHandler -= value;
  56. }
  57. }
  58. public double Bill { get; set; }
  59. public void PayTheBill()
  60. {
  61. Console.WriteLine("我要付钱{0}", Bill);
  62. }
  63. //顾客做了这个操作,就触发事件
  64. public void dian_cai()
  65. {
  66. if (this.orderEventHandler != null)
  67. {
  68. OrderEventArges e = new OrderEventArges();
  69. e.Cai_Name = "糖醋排骨";
  70. e.Size = "大";
  71. this.orderEventHandler.Invoke(this,e);
  72. }
  73. }
  74. }
  75. //声明一个【点菜事件】的参数类,继承EventArgs基类。包含了参数菜名,大份小份
  76. public class OrderEventArges : EventArgs
  77. {
  78. public string Cai_Name { get; set; }
  79. public string Size { get; set; }
  80. }
  81. //声明一个点菜事件的委托,第一个参数是事件的拥有者顾客,第二个参数是点菜事件的参数
  82. //为啥用EventHandler后缀,别人一看到这个后缀就知道这个委托是用来声明事件的,四个字约定俗成
  83. public delegate void OrderEventHandler(Customer customer, OrderEventArges e);

简略声明例子

  1. class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. //一个顾客,一个服务员
  6. Customer customer = new Customer();
  7. Waiter waiter = new Waiter();
  8. //事件订阅
  9. customer.Order += waiter.Action;
  10. //现在顾客开始点菜,点菜事件完成后,客户过得账单就更新了
  11. customer.dian_cai();
  12. customer.PayTheBill();
  13. Console.ReadLine();
  14. }
  15. }
  16. //服务员相当于订阅者
  17. public class Waiter
  18. {
  19. public void Action(object sender, EventArgs e)
  20. {
  21. //转换一个事件拥有者和事件参数
  22. Customer customer = sender as Customer;
  23. OrderEventArges oe = e as OrderEventArges;
  24. //订阅者可以通过事件传过来的参数获取事件信息
  25. Console.WriteLine("我给你上菜{0}",oe.Cai_Name);
  26. //根据菜的大小,算钱
  27. double price = 10;
  28. switch (oe.Size)
  29. {
  30. case "小":
  31. price = price * 0.5;
  32. break;
  33. case "大":
  34. price = price * 1.5;
  35. break;
  36. default:
  37. break;
  38. }
  39. //算完前给顾客加上
  40. customer.Bill += price;
  41. }
  42. }
  43. //一个客人类,里面有个方法,点菜了给账单付钱
  44. //顾客是事件拥有者,事件肯定在顾客里面啊,而且触发事件也在顾客内部触发
  45. public class Customer
  46. {
  47. //客户直接声明一个事件,用C#自带的EventHandler委托基类限制这个事件
  48. public event EventHandler Order;
  49. public double Bill { get; set; }
  50. public void PayTheBill()
  51. {
  52. Console.WriteLine("我要付钱{0}", Bill);
  53. }
  54. //顾客做了这个操作,就触发事件
  55. public void dian_cai()
  56. {
  57. if (this.Order != null)
  58. {
  59. OrderEventArges e = new OrderEventArges();
  60. e.Cai_Name = "糖醋排骨";
  61. e.Size = "大";
  62. this.Order.Invoke(this,e);
  63. }
  64. }
  65. }
  66. //声明一个【点菜事件】的参数类,继承EventArgs基类。包含了参数菜名,大份小份
  67. public class OrderEventArges : EventArgs
  68. {
  69. public string Cai_Name { get; set; }
  70. public string Size { get; set; }
  71. }
  72. //不用自己声明委托了,用C#自带的基委托
  73. //声明一个点菜事件的委托,第一个参数是事件的拥有者顾客,第二个参数是点菜事件的参数
  74. //为啥用EventHandler后缀,别人一看到这个后缀就知道这个委托是用来声明事件的,四个字约定俗成
  75. //public delegate void OrderEventHandler(Customer customer, OrderEventArges e);