supegong  

事件

在以往我们编写这类程序中,往往采用等待机制,为了等待某件事情的发生,需要不断地检测某些判断变量。

我们可以把事件编程简单地分成两个部分:事件发生的类(书面上叫事件发生器)和事件接收处理的类。事件发生的类就是说在这个类中触发了一个事件,但这个类并不知道哪个个对象或方法将会加收到并处理它触发的事件。所需要的是在发送方和接收方之间存在一个媒介。这个媒介在.NET Framework中就是委托(delegate)。在事件接收处理的类中,我们需要有一个处理事件的方法。

<1>因为在我们键盘按键事件中要包含按键信息,所以要派生一个KeyEventArgs类,来保存按键信息,好让后面知道按了哪个键。

<2>创建一个事件发生的类KeyInputMonitor,这个类用于监控键盘按键的输入并触发一个事件,但不知有无事件的接收类,即可取消事件的接收类class EventReceiver

<3>创建一个事件接收方的类,这个类先产生一个委托实例,再把这个委托实例添加到产生事件对象的事件列表中去,这个过程又叫订阅事件。然后提供一个方法回显按键信息。

<4> public KeyDown OnKeyDown; OnKeyDown==null时即没关联到函数,事件不执行。

<5>加入event后只能用+=,不能在接收方调用if (monitor.OnKeyDown != null) monitor.OnKeyDown(this, keyEventArgs)

<6>事件的接收方会创建委托的相关方法:monitor.OnKeyDown += new KeyInputMonitor.KeyDown(this.Echo)(在OnKeyDown(this, keyEventArgs)前会执行,如无,则OnKeyDown=null)

/// <summary>

    /// 按键信息类

    /// </summary>

    internal class KeyEventArgs : EventArgs

    {

        private char keyChar;

        public KeyEventArgs(char keyChar)

            : base()

        {

            this.keyChar = keyChar;

        }

 

        public char KeyChar

        {

            get

            {

                return keyChar;

            }

        }

    }

    /// <summary>

    /// 事件发生类

    /// </summary>

    internal class KeyInputMonitor

    {

        // 创建一个委托,返回类型为void,两个参数

        public delegate void KeyDown(object sender, KeyEventArgs e);

        /// <summary>

        /// 将创建的委托和特定事件关联,在这里特定的事件为OnKeyDown

        /// </summary>

 

        //public event KeyDown OnKeyDown;作用同下行

        public KeyDown OnKeyDown;

 

        public void Run()

        {

            bool finished = false;

            do

            {

                Console.WriteLine("Input a char");

                string response = Console.ReadLine();

 

                char responseChar = (response == "") ? ' ' : char.ToUpper(response[0]);

                switch (responseChar)

                {

                    case 'X':

                        finished = true;

                        break;

                    default:

                       // 得到按键信息的参数

                        KeyEventArgs keyEventArgs = new KeyEventArgs(responseChar);

                        // 触发事件

                        if (OnKeyDown == null)

                        {

                        }

                        else

                        {

                            OnKeyDown(this, keyEventArgs);

                        }

                       

                        break;

                }

            } while (!finished);

        }

    }

    /// <summary>

    /// 事件接收类

    /// </summary>

    internal class EventReceiver

    {

        public EventReceiver(KeyInputMonitor monitor)

        {

            // 产生一个委托实例并添加到KeyInputMonitor产生的事件列表中

            //monitor.OnKeyDown = new KeyInputMonitor.KeyDown(this.Echo);作用同下行

            monitor.OnKeyDown += new KeyInputMonitor.KeyDown(this.Echo);

            //KeyEventArgs keyEventArgs = new KeyEventArgs('5');

            //if (monitor.OnKeyDown != null) monitor.OnKeyDown(this, keyEventArgs);加入event参数后,此行错误(即禁止在事件的接收方强制调用事件)

        }

        private void Echo(object sender, KeyEventArgs e)

        {

            // 真正的事件处理函数

            Console.WriteLine("Capture key: {0}", e.KeyChar);

        }

    }   

    class Class1

    {

        public static void Main()

        {

            // 实例化一个事件发送器

            KeyInputMonitor monitor = new KeyInputMonitor();

            // 实例化一个事件接收器

            //EventReceiver eventReceiver = new EventReceiver(monitor);

            // 运行

            monitor.Run();

        }

    }

posted on 2011-02-28 15:31  supegong  阅读(448)  评论(0)    收藏  举报