C#基础——事件
事件具有以下特点:
1、发行者确定何时引发事件,订户确定执行何种操作来响应事件。
2、一个事件可以有多个订户,一个订户可处理来自多个发行者的多个事件。
3、没有订户的事件永远不会被调用。
4、事件通常用于通知用户操作。
5、如果一个事件有多个订户,当引发该事件时,会同步调用多个事件处理程序。
6、可以利用事件同步线程
7、在.NET Framework类库中,事件是基于EventHandler委托和EventArgs基类的。
示例1、发布事件
-
namespace DotNetEvents { //自定义EventArgs
-
public class CustomEventArgs:EventArgs { private string message; public CustomEventArgs(string s) { message=s; } public string Message { get{return message;} set{message=value;} } } //发布者
-
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(); } } }
输出:
示例2、引发派生类的基类事件
-
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(); } } }
输出:
示例3、实现接口事件
-
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(); } } }
输出: