• 在派生类中引发基类事件


    在基类中声明可以从派生类引发的事件的标准方法。此模式广泛应用于.Net Framework类库中的Windows窗体类。

    我们来看一个Button类的定义

        public class Button : ButtonBase, IButtonControl
        {
          protected override void OnClick(EventArgs e); //override基类的事件触发程序
        }

    我们通过ButtonBase最后找到基类Control

    public class Control : Component, IDropTarget, ISynchronizeInvoke, IWin32Window, IArrangedElement, IBindableComponent, IComponent, IDisposable
    {
        public event EventHandler Click;   //基类中定义事件
        protected virtual void OnClick(EventArgs e);//protected封装事件触发程序,允许继承类调用或重写
    }

    在包含事件的基类中创建一个受保护的调用方法。通过调用或重写方法,派生类便可以间接调用该事件。

    我们来看一个例子:

    namespace BaseClassEvents
    {
        
        //Special EventArgs class to hold info about Shapes.
        public class ShapeEventArgs:EventArgs
        {
            private double newArea;
            public ShapeEventArgs (double d)
            {
                newArea = d;
            }
            public double NewArea
            {
                get
                {
                    return newArea;
                }
            }
        }
        //Declare a delegate
        public delegate void CustomEventHandler(object sender, ShapeEventArgs e);
    
        //Base class event publisher
        public abstract class Shape
        {
            protected double area;
            public double Area
            {
                get
                {
                    return area;
                }
                set
                {
                    area = value;
                }
            }
            //raise an event
            public event CustomEventHandler ShapeChanged;
    
            public abstract void Draw();
    
            //event-invoking method
            protected virtual void OnShapeChanged(ShapeEventArgs e)
            {
                if(ShapeChanged !=null)
                {
                    ShapeChanged(this, e);
                }
            }
        }
        public class Circle:Shape
        {
            private double radius;
            public Circle (double d)
            {
                radius = d;
                area = 3.14 * radius * radius;
            }
            public void Update(double d)
            {
                radius = d;
                area = 3.14 * radius * 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");
            }
        }
    
        //Subscriber
        //Represents the surface on which the shapes are drawn
        //Subscibes to shape events so that it knows
        //when to redraw a shape
        public class ShapeContainer
        {
            List<Shape> _list;
            public ShapeContainer ()
            {
                _list = new List<Shape>();
            }
            public void AddShape(Shape s)
            {
                _list.Add(s);
                //Subscribe to the base class event.
                s.ShapeChanged += 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();
            }
        }
        class Program
        {
            static void Main(string[] args)
            {
                //Create the event publishers and subscriber
                Circle c1 = new Circle(54);
                Rectangle r1 = new Rectangle(12, 9);
                ShapeContainer sc = new ShapeContainer();
    
                //Add the shapes to the container
                sc.AddShape(c1);
                sc.AddShape(r1);
    
                //Cause some events to be raised
                c1.Update(57);
                r1.Update(7, 7);
    
                Console.ReadKey();
            }
        }
    }
  • 相关阅读:
    Profibus 接线
    如何正确使用Profibus插头以及终端电阻
    Java设计模式(3)——抽象工厂模式
    Java设计模式(2)——工厂方法模式
    Java设计模式(1)——简单工厂模式
    Oracle——控制事务
    Jackson-将对象转为Json字符串
    $.ajax
    Ajax——jQuery实现
    Ajax——三种数据传输格式
  • 原文地址:https://www.cnblogs.com/xiao9426926/p/5977004.html
Copyright © 2020-2023  润新知