• C#编程之委托与事件(二)


          我在上一篇文章(C#编程之委托与事件(一) )中通过示例结合的方法介绍了委托,在本文中,我同样以代码示例的方式来介绍C#里的事件机制。

    二、事件
      1.了解概念
         事件就是当对象或类状态发生改变时,对象或类发出的信息或通知。发出信息的对象或类称为"事件源",对事件进行处理的方法称为"接收者",通常事件源在发出状态改变信息时,它并不知道由哪个事件接收者来处理.这就需要一种管理机制来协调事件源和接收者,C++中通过函数指针来完成的.在C#中事件使用委托来为触发时将调用的方法提供类型安全的封装。

       在介绍事件之前我们先来了解几个事件的基本概念和几个重要素:
       --事件的本质
        -事件是特殊的委托实例
        -事件关键字:event

       --事件的四个要素:
        -定义事件
        -激发事件
        -监听事件
        -执行事件

      2.事件分析
        在.NET中,很多控件都有相关的事件,如Button的Click事件,它能响应鼠标的单击事件。
        --定义事件
    public delegate void EventHandler(object sender,EventArgs e);
    public event EventHandler Click;
      
       --激发事件:单击鼠标

       --监听事件
    this.button1.Click+=new EventHandler(this.button1_Click);
       
      --执行事件
    public void button1_Click(object sender,EventArgs e)

      
    //实现略
    }
        上面这个button的Click事件是我们最常见的,这里展示出了整个事件过程。接下来我们来看看一个简单的事件实例。

      3.简单实例--怎样定义一个完整的事件机制
        一.定义委托
    //定义事件委托
    public delegate void ChangedEventHandler(object sender, EventArgs e);
        二.定义事件
    //定义一个委托类型事件
    public event ChangedEventHandler Changed;
       三.触发事件
    //用于触发Changed事件
    protected virtual void OnChanged(EventArgs e)
    {
        
    if (this.Changed != null)
        
    {
             
    this.Changed(this, e);
        }

    }
       四.侦听事件
    MyText myText = new MyText();
    myText.Changed 
    += new MyText.ChangedEventHandler(myText_Chenged);
       五.事件处理程序
    //事件处理程序
    private static void myText_Chenged(object sender, EventArgs e)
    {
        Console.WriteLine(
    "Text属性的值改变:{0}", ((MyText)sender).Text);
    }
         这就完成了一个完整的事件机制,详细代码如下:
    MyText
    Program

      4.实例解说
         现在我们需要设计一个电子邮件程序,当收到电子邮件时,希望将该消息转发到传真机(Fax)和手机(CallPhone);
         一.我们需要传递消息则需要定义事件传递的消息类吧,定义如下:
     1namespace EventEmail
     2{
     3    //事件传递的消息定义
     4    public class MailMsgEventArgs:EventArgs
     5    {
     6        public readonly string from, to, subject, body;
     7
     8        public MailMsgEventArgs(string from, string to, string subject, string body)
     9        {
    10            this.from = from;
    11            this.to = to;
    12            this.subject = subject;
    13            this.body = body;
    14        }

    15    }

    16}
      
        二.定义委托及事件
    public delegate void MailMsgEventHandler(object sender,MailMsgEventArgs e);
    public event MailMsgEventHandler MailMsg;
          完整代码定义如下:
     1namespace EventEmail
     2{
     3    //定义一委托
     4    public delegate void MailMsgEventHandler(object sender,MailMsgEventArgs e);
     5
     6    public class MailManager
     7    {
     8        public event MailMsgEventHandler MailMsg;  //委托类型的事件
     9
    10        protected virtual void OnMailMsg(MailMsgEventArgs e)
    11        {
    12            if (this.MailMsg != null)
    13            {
    14                MailMsg(this, e);
    15            }

    16        }

    17
    18        //通过事件传递消息
    19        public void SimulateArrivingMsg(string from, string to, string subject, string body)
    20        {
    21            MailMsgEventArgs e = new MailMsgEventArgs(from, to, subject, body);
    22            OnMailMsg(e);
    23        }

    24    }

    25}

          三 .传真和手机的定义:
     1namespace EventEmail
     2{
     3    /// <summary>
     4    /// 传真机
     5    /// </summary>

     6    public class Fax
     7    {
     8        private TextBox _tBox;
     9        public Fax(MailManager mm, TextBox tBox)
    10        {
    11            //监听事件 
    12            //这里的FaxMsg,指的是符合MailMsgEventHandler委托的方法,也就是激发事件后所执行的方法
    13            mm.MailMsg += new MailMsgEventHandler(FaxMsg);
    14            _tBox = tBox;
    15        }

    16
    17        private void FaxMsg(Object sender, MailMsgEventArgs e)
    18        {
    19            _tBox.Text += string.Format("消息到传真:{4}来自:{0}{4}发到:{1}{4}主题:{2}{4}内容:{3}{4}{4}", e.from, e.to, e.subject, e.body, Environment.NewLine);
    20        }

    21
    22        public void Register(MailManager mm)
    23        {
    24            mm.MailMsg += new MailMsgEventHandler(FaxMsg);
    25        }

    26
    27        public void UnRegister(MailManager mm)
    28        {
    29            //注销事件
    30            mm.MailMsg -= new MailMsgEventHandler(FaxMsg);
    31        }

    32    }

    33}
    -----------------------------------------------------------------------------------------------------------
     1namespace EventEmail
     2{
     3    /// <summary>
     4    /// 手机
     5    /// </summary>

     6    public class CallPhone
     7    {
     8        private TextBox _tBox;
     9        public CallPhone(MailManager mm, TextBox tBox)
    10        {
    11            mm.MailMsg += new MailMsgEventHandler(CellPhoneMsg);
    12            _tBox = tBox;
    13        }

    14
    15        private void CellPhoneMsg(Object sender, MailMsgEventArgs e)
    16        {
    17            _tBox.Text += string.Format("消息到手机:{4}来自:{0}{4}发到:{1}{4}主题:{2}{4}内容:{3}{4}{4}", e.from, e.to, e.subject, e.body,Environment.NewLine);
    18        }

    19
    20        public void Register(MailManager mm)
    21        {
    22            mm.MailMsg += new MailMsgEventHandler(CellPhoneMsg);
    23        }

    24        public void UnRegister(MailManager mm)
    25        {
    26            mm.MailMsg -= new MailMsgEventHandler(CellPhoneMsg);
    27        }

    28    }

    29}
        四.客户端调用
            上面的逻辑处理完毕,下面来看看调用情况:
     1namespace EventEmail
     2{
     3    public partial class Form1 : Form
     4    {
     5        private Fax fax = null;
     6        private CallPhone cell = null;
     7        private MailManager mm = null;
     8        public Form1()
     9        {
    10            InitializeComponent();
    11            mm = new MailManager();
    12            fax = new Fax(mm, txtReceiver);
    13            cell = new CallPhone(mm, txtReceiver);
    14        }

    15
    16        private void Form1_Load(object sender, EventArgs e)
    17        {
    18
    19        }

    20
    21        private void btnSend_Click(object sender, EventArgs e)
    22        {
    23            mm.SimulateArrivingMsg(txtFrom.Text, txtTo.Text, txtSubject.Text, txtBody.Text);
    24        }

    25
    26        private void btnClear_Click(object sender, EventArgs e)
    27        {
    28            this.txtReceiver.Text = "";
    29        }

    30    }

    31}


    5 .事件的意义
       --有利于消息的传播
       --有利于模块之间的松散耦合

       注:什么是松散耦合?
       就以上面电子邮件程序为例。
       --如果没有事件机制,在发送邮件时,就需要去调用Fax,CellPhone的相关方法;
       --采用事件机制,在发送邮件时,仅许激发邮件管理器的事件既可,与Fax和CellPhone无关;
     
       也就是说,邮件管理器和Fax、CellPhone之间的依赖关系被解除了。
     
       本文就简单的介绍于此,上面看不太明白的可下示例程序了解;

       示例程序在载:EventDemo.rar

    ------------------------------------------------------------------------------------------------------------

  • 相关阅读:
    生成函数代替伯努利数
    关于费用流
    GDOI注意事项
    计算几何 学习笔记
    jzoj5370
    图上的游戏
    小学生语文题
    arcane
    P2305 [NOI2014] 购票
    P3512 [POI2010]PIL-Pilots
  • 原文地址:https://www.cnblogs.com/beniao/p/1158940.html
Copyright © 2020-2023  润新知