C#程式設計之委託與事件(二)

iDotNetSpace發表於2009-05-15

     我在上一篇文章(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
 1using System;
 2using System.Collections.Generic;
 3using System.Text;
 4
 5namespace EventExample1
 6{
 7    public class MyText
 8    {
 9        //定義事件委託
10        public delegate void ChangedEventHandler(object sender, EventArgs e);
11
12        //定義一個委託型別事件
13        public event ChangedEventHandler Changed;
14
15        //用於觸發Changed事件
16        protected virtual void OnChanged(EventArgs e)
17        {
18            if (this.Changed != null)
19            {
20                this.Changed(this, e);
21            }
22        }
23
24        private string _text = string.Empty;
25        public string Text
26        {
27            get { return this._text; }
28            set
29            {
30                this._text = value;
31                this.OnChanged(new EventArgs());
32            }
33        }
34    }
35}
36Program
 1using System;
 2using System.Collections.Generic;
 3using System.Text;
 4
 5namespace EventExample1
 6{
 7    class Program
 8    {
 9        static void Main(string[] args)
10        {
11            MyText myText = new MyText();
12            myText.Changed += new MyText.ChangedEventHandler(myText_Chenged);
13
14            string str = string.Empty;
15            while (str != "exit")
16            {
17                Console.Write("請輸入一個字串:");
18                str = Console.ReadLine();
19                myText.Text = str;
20            }
21        }
22
23        //事件處理程式
24        private static void myText_Chenged(object sender, EventArgs e)
25          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    /**////


 4    /// 傳真機
 5    ///

 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    /**////
 4    /// 手機
 5    ///

 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之間的依賴關係被解除了。
 
   本文就簡單的介紹於此,上面看不太明白的可下示例程式瞭解;

 

 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-598258/,如需轉載,請註明出處,否則將追究法律責任。

相關文章