程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C# 關於事件

C# 關於事件

編輯:C#入門知識

關於事件

要了解事件的機制,首先要明白委托的機制。事件機制主要分為事件的聲明,事件的觸發,事件的響應。事件的觸發者成為“發布者”,事件的響應者成為事件的“訂閱者”

事件特征:
發行者確定何時引發事件,訂戶確定執行何種操作來響應該事件。
一個事件可以有多個訂戶。 一個訂戶可處理來自多個發行者的多個事件。
沒有訂戶的事件永遠也不會引發。
事件通常用於通知用戶操作,例如,圖形用戶界面中的按鈕單擊或菜單選擇操作。
如果一個事件有多個訂戶,當引發該事件時,會同步調用多個事件處理程序。 要異步調用事件,請參見使用異步方式調用同步方法。
在 .NET Framework 類庫中,事件是基於 EventHandler 委托和 EventArgs 基類的。


事件的發布和訂閱:
事件的發布類中一般包括事件的聲明,事件的激發(其實也就是響應,但是響應函數中一定要用到委托)。事件的訂閱者要用事件發布類的變


量(用來指定委托對應的函數),事件響應函數。示例:

class Publish
    {
        public event EventHandler eventName; //declare event named eventName


        public void inspireEvent()           // inspire the event
        {
            onEventName(new EventArgs());
        }


        public void onEventName(EventArgs e) // will use the scriber's method to reply the event
        {
            EventHandler handle = eventName;
            if (handle != null)
            {
                handle(this,e);
            }
        }
    }


class Scriber
    {
        public Scriber(Publish pb)
        {
            pb.eventName += howDo; // scribe the event
        }


        public void howDo(Object sender, EventArgs e)
        {
            Console.WriteLine("what a fuck day it is");
        }
    }

class Program
    {
        static void Main(string[] args)
        {
            Publish ph = new Publish();
            Scriber sb = new Scriber(ph);


            ph.inspireEvent();		//motivate the event
        }
    }

事件的獨特性:
事件是委托,但是它是特殊的委托,調用事件只能在聲明事件的類中,在事件的派生類中不能出現諸如:
EventHandler handle = eventBase;
eventBase(obj,e);
只能出現 eventBase+=,eventBase-=。
所以如果要調用基類中的事件只能通過間接的方式,示例如下:
 class BaseEvent
    {
        public event EventHandler baseEvent;


        public virtual void draw()
        {
            Console.WriteLine("This is in base draw");
        }


        public virtual void onDraw(EventArgs e)
        {
            EventHandler handle = baseEvent;
            if (handle != null)
            {
                handle(this ,e);
            }
            Console.WriteLine("this is in base on");
        }
    }


class Derived : BaseEvent
    {
        public override void draw()
        {
            //base.draw();
            Console.WriteLine("this is in derived class");
        }


        public override void onDraw(EventArgs e)
        {
            //EventHandler handle = baseEvent;
            //baseEvent(this, e);


            base.onDraw(e);
            
        }


        public void motivateDraw()
        {
            onDraw(new EventArgs());
        }
    }


class Scribe
    {
        public Scribe(Derived dr)
        {
            dr.baseEvent += Motive;
        }


        public void Motive(Object sender, EventArgs e)
        {
            Console.WriteLine("what a fuck day");
        }
    }

class Program
    {
        static void Main(string[] args)
        {
            Derived D = new Derived();
            BaseEvent B = new BaseEvent();
            Scribe Sb = new Scribe(D);
            D.motivateDraw();
        }
    }

接口事件的實現:
接口事件的實現和接口中方法,屬性的實現基本相同。當訂閱事件的時候,訂閱的方法通過事件訪問器添加到委托的方法列表中,事件訪問器類似於屬性訪問器,不過訪問器被命名為add,remove。在大多數情況下都不需要自定義事件訪問器,因為編譯器會幫我們制定,但是當編譯器不能幫我們制定的時候,我們就得自己去寫事件訪問器了。當多個接口中含有具有相同簽名的事件的時候,這個時候就得使用事件的顯示定義了,並且在事件的訂閱的時候使用接口來調用(這裡很類似屬性,索引器,方法),示例如下:
namespace ConsoleApplication16InterfaceEvent
{
    interface Iface
    {
        event EventHandler faceEvent;
    }


    interface Ifoot
    {
        event EventHandler footEvent;
    }


    interface Ihand
    {
        event EventHandler footEvent;
    }
    class InterEvent : Iface,Ifoot,Ihand
    {
        public event EventHandler faceEvent;
        //public event EventHandler footEvent;
        public event EventHandler preFootEvent;
        public event EventHandler nexHandEvent;


        Object objectLock = new Object();


        event EventHandler Ifoot.footEvent
        {
            add 
            {
                lock (objectLock)
                {
                    preFootEvent += value;
                }
            }
            remove
            {
                lock (objectLock)
                {
                    preFootEvent -= value;
                }
            }
        }


        event EventHandler Ihand.footEvent
        {
            add 
            {
                lock (objectLock)
                {
                    nexHandEvent += value;
                }
            }


            remove
            {
                lock (objectLock)
                {
                    nexHandEvent -= value;
                }
            }
        }


        public void finger()
        {
            EventHandler handle = preFootEvent;
            if ( handle != null)
                preFootEvent(this,new EventArgs());


            handle = nexHandEvent;
            if (handle != null)
                nexHandEvent(this,new EventArgs());
        }
    }


}


//...............
namespace ConsoleApplication16InterfaceEvent
{
    class Scribe
    {
        public Scribe(InterEvent Et)
        {
            Ifoot foot = (Ifoot)Et;
            foot.footEvent += draw1;


            Ihand hand = (Ihand)Et;
            hand.footEvent += draw2;


            
        }


        void draw1(Object sender, EventArgs e)
        {
            Console.WriteLine("this is in Scribe draw1");
        }


        void draw2(Object sender, EventArgs e)
        {
            Console.WriteLine("this is in Scribe draw2");
        }
    }
}


//..................
namespace ConsoleApplication16InterfaceEvent
{
    class Program
    {
        static void Main(string[] args)
        {
            InterEvent EI = new InterEvent();
            Scribe Sb = new Scribe(EI);
            EI.finger();
        }
    }
}


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved