zoukankan      html  css  js  c++  java
  • C# 标准事件模式

    .NET框架为事件定义了一个标准模式,它的目的是保持框架和用户代码之间的一致性。

    标准事件的模式核心是SystemEventArgs——预定义的没有成员的框架类(不同于静态Empty属性)

    EventArgs表示包含事件数据的类的基类,并提供用于不包含事件数据的事件的值。用于为事件传递信息的基类。

    在下面例子中,我们定义EventArgs的子类,用于事件PriceChanged被引发时,传递新旧Price值:

        public class PriceChangedEventArgs : EventArgs
        {
            public readonly decimal LastPrice;
            public readonly decimal NewPrice;
    
            public PriceChangedEventArgs(decimal lastPrice, decimal newPrice)
            {
                LastPrice=lastPrice;
                NewPrice= newPrice;
            }
        }

    考虑到复用性,EventArgs子类根据它包含的内容命名(而非根据将被使用的事件命名)。

    选择或定义事件的委托,需遵循三条原则:

    • 委托必须以void作为返回值
    • 委托必须接受两个参数:第一个是object类,第二个是EventArgs的子类。
    • 委托的名称必须以EventHandler结尾

    完整例子:

    class Test 
            public static void Main()
            {
                InitializeComponent();
                Stock stock = new Stock("THPW");
                stock.Price = 27.10M;
                //注册PriceChanged事件
                stock.PriceChanged += stock_PriceChanged;
                stock.Price = 31.59M;
            }
    
            static void stock_PriceChanged(object sender, PriceChangedEventArgs e)
            {
                if ((e.NewPrice - e.LastPrice) / e.LastPrice > 0.1M)
                {
                    Console.WriteLine("Alert,10% stock increase!");
                }
            }
        }
    
        public class Stock
        {
            string symbol;
            decimal price;
    
            public Stock(string symbol)
            {
                this.symbol = symbol;
            }
    
    //定义委托事件
    public event EventHandler<PriceChangedEventArgs> PriceChanged;
    protected virtual void OnPriceChanged(PriceChangedEventArgs e) { if (PriceChanged != null) PriceChanged(this, e); } public decimal Price { get { return price; } set { if (price == value) return;
                price = value;
              OnPriceChanged(new PriceChangedEventArgs(price, value));
                    
                }
            }
        }
    
        public class PriceChangedEventArgs : EventArgs
        {
            public readonly decimal LastPrice;
            public readonly decimal NewPrice;
    
            public PriceChangedEventArgs(decimal lastPrice, decimal newPrice)
            {
                LastPrice=lastPrice;
                NewPrice= newPrice;
            }
        }    

    如果事件不传递额外的信息,可以使用预定义的非泛化委托EventHandler。如下所示:

        class Test
        {
            public static void Main()
            {
                InitializeComponent();
                Stock stock = new Stock();
                stock.Price = 27.10M;
                //注册PriceChanged事件
                stock.PriceChanged += stock_PriceChanged;
                stock.Price = 31.59M;
            }
    
            static void stock_PriceChanged(object sender, EventArgs e)
            {
               Console.WriteLine("价格变换了!");
            }
        }
    
        public class Stock
        {
            decimal price;
    
            public event EventHandler PriceChanged;
    
            protected virtual void OnPriceChanged(EventArgs e)
            {
                if (PriceChanged != null) PriceChanged(this, e);
            }
    
            public decimal Price
            {
                get { return price; }
                set
                {
                    if (price == value) return;
                    price = value;
    
                    //OnPriceChanged(new EventArgs());
    
                    OnPriceChanged(EventArgs.Empty);
                }
            }
        }

    注意:

    上面例子中事件除了传递已发生信息,没有传递其他信息。

    你可以使用 OnPriceChanged(new EventArgs()) 来完成事件的传递。

    为了避免对EventArgs不必要的初始化,建议使用EventArgs.Empty属性。使用这样一个“空的”静态引用的对象,避免多余地去创建一个新对象。

    微软的大部分控件所抛出的事件都有两个参数,第一个是 object 类型的,第二个是 EventArgs 类型的。

    你从EventArgs  e那里得不到任何此次事件相关需要传递的信息,真正传递的信息都在sender中。

  • 相关阅读:
    Oracle 获取本周、本月、本季、本年的第一天和最后一天(转载)
    easyui tabs页签显示在底部属性
    java mybatis XML文件中大于号小于号转义(转载)
    原生JS日历 + JS格式化时间格式
    ajax之async属性
    Easyui 行编辑
    css中实现显示和隐藏(转)
    layer弹出层 获取index
    js中关于json常用的内容、js将数字保留两位小数
    发布项目到github上web服务器来运行
  • 原文地址:https://www.cnblogs.com/LemonFive/p/9002239.html
Copyright © 2011-2022 走看看