zoukankan      html  css  js  c++  java
  • 事件

    一、事件初印象

    首先看个播放器的案例

     1 class Program
     2     {
     3         static void Main(string[] args)
     4         {
     5             MP3 m = new MP3();
     6 
     7             //启动前
     8             m.BeforeStartMP3 = () => { Console.WriteLine("初始化歌词!"); };
     9 
    10             m.BeforeStopMP3 = () => { Console.WriteLine("保存当前进度!"); };
    11 
    12             m.Start();
    13 
    14             m.TurnOffPower();
    15 
    16             Console.ReadKey();
    17         }
    18     }
    19 
    20     public class MP3
    21     {
    22 
    23         //在启动或者关闭mp3之前,每个人想进行的操作可能不同,这里用委托实现用户的自定义操作
    24         public Action BeforeStartMP3;
    25         public Action BeforeStopMP3;
    26 
    27         /// <summary>
    28         /// 播放音乐
    29         /// </summary>
    30         public void PlayMusic()
    31         {
    32             Console.WriteLine("音乐播放中……");
    33         }
    34 
    35 
    36         /// <summary>
    37         /// 启动mp3
    38         /// </summary>
    39         public void Start()
    40         {
    41             if (BeforeStartMP3!=null)
    42             {
    43                 //在启动播放的时候,触发了这个事件
    44                 BeforeStartMP3();
    45             }
    46 
    47             PlayMusic();
    48         }
    49 
    50         public void TurnOffPower()
    51         {
    52             if (BeforeStopMP3 != null)
    53             {
    54                 //在停止播放之前触发了这个事件
    55                 BeforeStopMP3();
    56             }
    57 
    58             Stop();
    59 
    60         }
    61 
    62         /// <summary>
    63         /// 关闭mp3
    64         /// </summary>
    65         public void Stop()
    66         {
    67             Console.WriteLine("停止播放音乐……");
    68         }
    69 
    70 
    71     }
    View Code

    上面的例子虽然是用委托实现的,但是达到了使用事件的效果。

    二、事件进阶

    先用委托来模拟实现三连击的效果

    用户自定义控件中的代码:

     1 namespace 事件进阶
     2 {
     3     public partial class UCTripleButton : UserControl
     4     {
     5         public UCTripleButton()
     6         {
     7             InitializeComponent();
     8         }
     9 
    10         public Action TripleClick;
    11 
    12         int count = 0;
    13         private void btnTripleClick_Click(object sender, EventArgs e)
    14         {
    15             count++;
    16             if (count>=3)
    17             {
    18                 //MessageBox.Show("点击了三次!");
    19                 if (TripleClick!=null)
    20                 {
    21                     TripleClick();
    22                 }
    23                 count = 0;
    24             }
    25         }
    26     }
    27 }
    View Code

    Form1中的代码:

     1 public partial class Form1 : Form
     2     {
     3         public Form1()
     4         {
     5             InitializeComponent();
     6         }
     7 
     8         private void Form1_Load(object sender, EventArgs e)
     9         {
    10             //将方法传给委托变量
    11             ucTripleButton1.TripleClick = Form1TripleClick;
    12         }
    13 
    14         private void Form1TripleClick()
    15         {
    16             MessageBox.Show("这是Form1");
    17         }
    18 
    19         //在用户控件外面调用,点击一次就能弹出三连击的效果
    20         private void button1_Click(object sender, EventArgs e)
    21         {
    22             if (ucTripleButton1.TripleClick!=null)
    23             {
    24                 ucTripleButton1.TripleClick();
    25             }
    26         }
    27 
    28         //委托变量是public,可以在外面调用
    29         private void button2_Click(object sender, EventArgs e)
    30         {
    31             ucTripleButton1.TripleClick=null;
    32         }
    33     }
    View Code

    Form2中的代码:

     1 namespace 事件进阶
     2 {
     3     public partial class Form2 : Form
     4     {
     5         public Form2()
     6         {
     7             InitializeComponent();
     8         }
     9 
    10         private void Form2_Load(object sender, EventArgs e)
    11         {
    12             ucTripleButton1.TripleClick = Form2TripleClick;
    13         }
    14 
    15         private void Form2TripleClick()
    16         {
    17             MessageBox.Show("这是Form2");
    18         }
    19     }
    20 }
    View Code

    这样能实现三连击事件的效果,但是我们在Form1窗口中增加其他按钮,由于委托是public,button2可以直接调用绑定的方法,button3可以清除委托绑定的方法,这样调用委托的权限容易被改变(在类的外部随意调用),如同别人可以操作你的银行卡,很显然,不合理。于是就有了事件。

    事件只能在类的内部被触发,但是可以在外部绑定或者取消。

    编写事件的代码:

     1 public partial class UCTripleButton : UserControl
     2     {
     3         public UCTripleButton()
     4         {
     5             InitializeComponent();
     6         }
     7 
     8 
     9         //Action前面加上event关键字,就变成了事件
    10         public event Action TripleClick;
    11 
    12         int count = 0;
    13         private void btnTripleClick_Click(object sender, EventArgs e)
    14         {
    15             count++;
    16             if (count>=3)
    17             {
    18                 //MessageBox.Show("点击了三次!");
    19                 if (TripleClick!=null)
    20                 {
    21                     TripleClick();
    22                 }
    23                 count = 0;
    24             }
    25         }
    26     }
    View Code

    Form1触发事件:

     1 namespace 事件进阶
     2 {
     3     public partial class Form1 : Form
     4     {
     5         public Form1()
     6         {
     7             InitializeComponent();
     8         }
     9 
    10         private void Form1_Load(object sender, EventArgs e)
    11         {
    12             //将方法传给委托变量
    13             //ucTripleButton1.TripleClick = Form1TripleClick;
    14 
    15             //事件只能用+=,-=绑定,避免被随意调用和赋值的时候被全部清空
    16             ucTripleButton1.TripleClick += UcTripleButton1_TripleClick;
    17         }
    18 
    19         private void UcTripleButton1_TripleClick()
    20         {
    21             MessageBox.Show("这是Form1");
    22         }
    23 
    24         private void Form1TripleClick()
    25         {
    26             MessageBox.Show("这是Form1");
    27         }
    28 
    29         //在用户控件外面调用,点击一次就能弹出三连击的效果
    30         private void button1_Click(object sender, EventArgs e)
    31         {
    32             //if (ucTripleButton1.TripleClick!=null)
    33             //{
    34             //    ucTripleButton1.TripleClick();
    35             //}
    36 
    37             ucTripleButton1.TripleClick += UcTripleButton1_TripleClick;
    38         }
    39 
    40         //委托变量是public,可以在外面调用
    41         private void button2_Click(object sender, EventArgs e)
    42         {
    43             //ucTripleButton1.TripleClick=null;
    44             ucTripleButton1.TripleClick += null;
    45         }
    46     }
    47 }
    View Code

    三、补充

    回到第一个案例,我们用委托实现了播放器在播放歌曲的时候实现了加载歌词,保存进度的功能 ,但是由于委托是public的,所以也可以直接调用加载歌词和保存进度的方法,根本不需要启动和关闭播放器,就能直接实现这个效果,很显然这不合理。这里可以用事件改造。

     四、事件和委托的区别

    委托是一种数据类型,事件是一个对象,它是基于委托实现的,对委托进行了封装。二者没有可比性。

  • 相关阅读:
    Java虚拟机------JVM内存区域
    Java虚拟机------垃圾收集器
    Java虚拟机--------JVM常见参数
    Kafka和的安装与配置
    Kafka介绍与消息队列
    Kafka命令操作
    Kafka深度解析
    Flume架构
    四十三、NPM报错ERR! code UNABLE_TO_VERIFY_LEAF_SIGNATURE
    四十二、在线预览pdf文件
  • 原文地址:https://www.cnblogs.com/wesley168/p/6797578.html
Copyright © 2011-2022 走看看