浅析C# 中object sender与伊夫ntArgs e(转)

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

一、了解C#中的预订义事件管理机制

标准事件的形式基本是System伊芙ntArgs——预约义的从未有过成员的框架类(不一致于静态Empty属性)

    
在写代码前大家先来熟练.net框架花潮事件有关的类和信托,掌握C#中预订义事件的拍卖。

伊芙ntArgs代表包蕴事件数量的类的基类,并提供用于不包涵事件数量的轩然大波的值。用于为事件传递音讯的基类。

     EventArgs是富含事件数量的类的基类,用于传递事件的底细。

在底下例子中,大家定义伊芙ntArgs的子类,用于事件PriceChanged被吸引时,传递新旧Price值:

     EventHandler是三个信托注明如下

    public class PriceChangedEventArgs : EventArgs
    {
        public readonly decimal LastPrice;
        public readonly decimal NewPrice;

        public PriceChangedEventArgs(decimal lastPrice, decimal newPrice)
        {
            LastPrice=lastPrice;
            NewPrice= newPrice;
        }
    }

          public delegate void EventHandler( object sender , EventArgs
e )

思量到复用性,伊夫ntArgs子类根据它包括的情节命名(而非根据将被选用的轩然大波命名)。

    
注意这里的参数,前者是1个对象(其实这里传递的是目标的引用,假诺是button一的click事件则sender正是button1),后边是含有事件数量的类的基类。

分选或概念事件的嘱托,需依据3条规则:

    
下边大家研究一下Button类看看里面包车型大巴轩然大波表明(使用WinCV工具查看),以Click事件为例。

  • 寄托必须以void作为再次来到值
  • 信托必须接受七个参数:第四个是object类,第2个是伊夫ntArgs的子类。
  • 寄托的称谓必须以伊芙ntHandler结尾

          public event EventHandler Click;

 

     这里定义了三个伊夫ntHandler类型的风浪Click

完全例子:

    
前面的始末都以C#在类库中曾经为大家定义好了的。上面大家来看编制程序时产生的代码。

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;
        }
    }    

         private void button1_Click(object sender, System.EventArgs
e)
         {
             …
         }

 

    
那是我们和button一_click事件所对应的章程。注意方式的参数符合委托中的签字(既参数列表)。这大家怎么把这几个措施和事件联系起来呢,请看上边包车型客车代码。

即使事件不传递额外的音信,能够利用预订义的非泛化委托伊夫ntHandler。如下所示:

         this.button1.Click += new
System.EventHandler(this.button1_Click);

    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);
            }
        }
    }

     把this.button1_Click方法绑定到this.button壹.Click事变。

 

    
上边我们商量一下C#事件管理的做事流程,首先系统会在为大家创制1个在后台监听事件的对象(若是是
button一的风浪那么监听事件的就是button一),这么些目的用来发出事件,假如有某些用户事件发生则发出相应的应用程序事件,然后实施订阅了风浪的保有办法。

注意:

②、轻巧的自定义事件(一)

地点例子中事件除了传递已产生音讯,未有传递别的音信。

     首先大家要求定义2个类来监听客户端事件,这里大家监听键盘的输入。

您能够采纳 OnPriceChanged(new 伊夫ntArgs()) 来成功事件的传递。

     定义贰个委托。

为了制止对伊芙ntArgs不供给的发轫化,提出采用伊芙ntArgs.Empty属性。使用那样三个“空的”静态引用的对象,制止多余地去创立四个新目标。

         public delegate void UserRequest(object sender,EventArgs e);

 

    
前边的object用来传递事件的爆发者,前边的伊芙ntArgs用来传递事件的细节,今后权且没什么用处,1会末尾的例子中将使用。

微软的绝大许多控件所抛出的轩然大波都有两个参数,第二个是 object 类型的,第二个是 伊芙ntArgs 类型的。

     上边定义三个此委托项目类型的风波

图片 1

         public event UserRequest OnUserRequest;

你从伊夫ntArgs 
e那里得不到任何这次风浪有关要求传递的音讯,真正传递的音信都在sender中。

     下边大家来做三个死循环

         public void Run()
       {
       bool finished=false;
       do
       {
        if (Console.ReadLine()=="h")
        {
         OnUserRequest(this,new EventArgs());
        }  
       }while(!finished);
       }

    
此代码不断的渴求用户输入字符,假设输入的结果是h,则触发OnUserRequest事件,事件的触发者是自己(this),事件细节无(未有传递任何参数的伊芙ntArgs实例)。我们给这些类取名称为UserInputMonitor。

    下面我们要做的是定义客户端的类
     首先得实例化UserInputMonitor类

        UserInputMonitor monitor=new UserInputMonitor();

     然后大家定义三个艺术。

       private void ShowMessage(object sender,EventArgs e)
       {
           Console.WriteLine(“HaHa!!”);
       }

     
最终要做的是把这一个措施和事件联系起来(订阅事件),大家把它写到库户端类的构造函数里。

相关文章