C#基础——事件

    事件具有以下特点:

    1、发行者确定何时引发事件,订户确定执行何种操作来响应事件。

    2、一个事件可以有多个订户,一个订户可处理来自多个发行者的多个事件。

    3、没有订户的事件永远不会被调用。

    4、事件通常用于通知用户操作。

    5、如果一个事件有多个订户,当引发该事件时,会同步调用多个事件处理程序。

    6、可以利用事件同步线程

    7、在.NET Framework类库中,事件是基于EventHandler委托和EventArgs基类的。

示例1、发布事件

  1. namespace DotNetEvents
    {
        //自定义EventArgs
  2.     public class CustomEventArgs:EventArgs
        {
            private string message;
            public CustomEventArgs(string s)
            {
                message=s;
            }
            public string Message
            {
                get{return message;}
                set{message=value;}
            }
        }
        //发布者
  3.     class Publisher
        {
            public event EventHandler<CustomEventArgs> RaiseCustomEvent;
            public void DoSomething()
            {
                OnRaiseCustomEvent(new CustomEventArgs("Did something"));
            }
            protected virtual void OnRaiseCustomEvent(CustomEventArgs e)
            {
                EventHandler<CustomEventArgs> handler=RaiseCustomEvent;
                if(handler!=null)
                {
                    e.Message+= String.Format(" at {0}", DateTime.Now.ToString());
                    handler(this,e);
                }
            }
        }
        class Subscriber
        {
            private string id;
            public Subscriber(string ID,Publisher pub)
            {
                id=ID;
                pub.RaiseCustomEvent+=HandleCustomEvent;
            }
            void HandleCustomEvent(object sender, CustomEventArgs e)
            {
                Console.WriteLine(id + " received this message: {0}", e.Message);
            }
        }
        public class Program
       {
           public static void Main()
        {
            Publisher pub=new Publisher();
            Subscriber sub1=new Subscriber("sub1",pub);
            Subscriber sub2=new Subscriber("sub2",pub);
            pub.DoSomething();
            Console.ReadLine();
        }
    }
    }

输出:

image

示例2、引发派生类的基类事件

  1. namespace BaseClassEvents
    {
        public class ShapeEventArgs:EventArgs
        {
            private double newArea;
            public ShapeEventArgs(double d)
            {
                newArea=d;
            }
            public double NewArea
            {
                get{return newArea;}
            }
        }
        public abstract class Shape
        {
            protected double area;
            public double Area
            {
                get{return area;}
                set{area=value;}
            }
            public event EventHandler<ShapeEventArgs> ShapeChangeed;
            public abstract void Draw();
            protected virtual void OnShapeChanged(ShapeEventArgs e)
            {
                EventHandler<ShapeEventArgs> handler=ShapeChangeed;
                if(handler!=null)
                {
                    handler(this,e);
                }
            }
        }
        public class Circle:Shape
        {
            private double radius;
            public Circle(double d)
            {
                radius=d;
                area=3.14*radius;
            }
            public void Update(double d)
            {
                radius=d;
                area=3.14*radius;
                OnShapeChanged(new ShapeEventArgs(area));
            }
            protected override void OnShapeChanged(ShapeEventArgs e)
            {
                base.OnShapeChanged(e);
            }
            public override void Draw()
            {
                Console.WriteLine("Drawing a circle");
            }
        }
        public class Rectangle:Shape
        {
            private double length;
            private double width;
            public Rectangle(double length,double width)
            {
                this.length=length;
                this.width=width;
                area=length*width;
            }
            public void Update(double length,double width)
            {
                this.length=length;
                this.width=width;
                area=length*width;
                OnShapeChanged(new ShapeEventArgs(area));
            }
            protected override void OnShapeChanged(ShapeEventArgs e)
            {
                base.OnShapeChanged(e);
            }
            public override void Draw()
            {
                Console.WriteLine("Drawing a rectangle");
            }
        }
        public class ShapeContainer
       {
            List<Shape> _list;
            public ShapeContainer()
            {
                _list=new List<Shape>();
            }
            public void AddShape(Shape s)
            {
                _list.Add(s);
                s.ShapeChangeed+=HandleShapeChanged;
            }
            private void HandleShapeChanged(object sender,ShapeEventArgs e)
            {
                Shape s=(Shape)sender;
                Console.WriteLine("Received event. Shape area is now {0}", e.NewArea);
                s.Draw();
            }
        }
        public class Program
    {
        public static void Main()
        {
            Circle c1=new Circle(50);
            Rectangle r1=new Rectangle(15,12);
            ShapeContainer sc=new ShapeContainer();
            sc.AddShape(c1);
            sc.AddShape(r1);
            c1.Update(60);
            r1.Update(20,15);
            Console.WriteLine("Press Enter to close this window.");
            Console.ReadLine();
        }
    }
    }

输出:

image

示例3、实现接口事件

  1. namespace WrapTwoInterfaceEvents
    {
        using System;
        public interface IDrawingObject
        {
            event EventHandler OnDraw;
        }
        public interface IShape
        {
            event EventHandler OnDraw;
        }
        public class Shape : IDrawingObject, IShape
        {
            event EventHandler PreDrawEvent;
            event EventHandler PostDrawEvent;
            event EventHandler IDrawingObject.OnDraw
            {
                add { PreDrawEvent += value; }
                remove { PreDrawEvent -= value; }
            }
            event EventHandler IShape.OnDraw
            {
                add { PostDrawEvent += value; }
                remove { PostDrawEvent -= value; }
            }
            public void Draw()
            {
                EventHandler handler = PreDrawEvent;
                if (handler != null)
                {
                    handler(this, new EventArgs());
                }
                Console.WriteLine("Drawing a shape.");
                handler = PostDrawEvent;
                if (handler != null)
                {
                    handler(this, new EventArgs());
                }
            }
        }
        public class Subscriber1
        {
            public Subscriber1(Shape shape)
            {
                IDrawingObject d = (IDrawingObject)shape;
                d.OnDraw += new EventHandler(d_OnDraw);
            }
    
            void d_OnDraw(object sender, EventArgs e)
            {
                Console.WriteLine("Sub1 receives the IDrawingObject event.");
            }
        }
        public class Subscriber2
        {
            public Subscriber2(Shape shape)
            {
                IShape d = (IShape)shape;
                d.OnDraw += new EventHandler(d_OnDraw);
            }
            void d_OnDraw(object sender, EventArgs e)
            {
                Console.WriteLine("Sub2 receives the IShape event.");
            }
        }
        public class Program
        {
            static void Main(string[] args)
            {
                Shape shape = new Shape();
                Subscriber1 sub = new Subscriber1(shape);
                Subscriber2 sub2 = new Subscriber2(shape);
                shape.Draw();
                Console.WriteLine("Press Enter to close this window.");
                Console.ReadLine();
            }
        }
    }

输出:

image

posted @ 2010-01-06 00:41  Asharp  阅读(890)  评论(0编辑  收藏  举报