zoukankan      html  css  js  c++  java
  • 事件--c#

    以上是事件的几个操作。

    事件由五个组件构成:

    具体作用如下:

    事件声明:

    event  委托类型 事件名;例子:

    public event EventHandler Elapsed;

    还可同时声明几个事件:

    public event EventHandler    Event1,Event2,Event3;

    还可添加static使得事件静态。

    事件说明

    事件是成员,不是类型,所以不能通过new来创建他的对象。

    由于是成员:

    1,他必须声明在类或者结构中,和其他成员一样。

    2,不能在一段可执行代码中声明事件。

    委托类型和eventhandler。

    事件必须要有委托类型,我们可以声明一个委托类型或者使用一个已经存在的。

    如果声明一个类型,必须指定方法保存的签名和返回类型。

    更好的办法是,使用eventhandler。

    public delegate void Eventhandler(Object obj,EventArgs e);

    事件触发

    事件触发和委托一样,都是:事件名(参数,参数);

    触发事件必须先判断事件是否null,确认有方法可以执行。 

    例如:

    if(Elapsed!=null)
        Elapsed(sourse,args);

    把事件声明和触发事件代码放在一起,便有了如下发布者类声明。该代码保护两个成员,事件和一个叫onOneSecond()方法。它触发了事件。

    public class MyTimerClass
       {
           public event EventHandler Elapse;
            private void onOneSecond(object obj,EventArgs args)
           {
                if(Elapse!=null)
                    Elapse(obj,args); //发起事件。
           }
           //下面的代码确认每1秒调用一次onOneSecond()方法。
       }

    记住两点:

    1)发布者类有一个作为成员的事件,

    2)类包含了触发事件的代码。

    事件订阅方式:

    要为事件添加事件处理程序,处理程序必须和委托有一样返回值类型和签名。

    使用+=运算符为事件增加事件处理程序。

    方法可以是下面任何一个:

    1)实例方法  2)静态方法  3)匿名方法  4)lambda表达式。

    下面代码为Elapsed事件增加三个方法。

    类        
    
    mc.Elapsed+=ca.TimerHandlerA;   实例方法
    
    mc.Elapsed+=classB.TimerHandlerB;  静态方法
    
    mc.Elapsed+=new EventHandler(cc.TimerHandlerC);  委托形式。

    和委托一样,我们可以使用匿名方法和lambda表达式来增加事件处理程序。例如,如下代码先使用lambda表达式后使用了匿名方法。

                mc.Elapsed+=(source,args)=>
                    {
                        Console.WriteLine("lambda expression");
                    }
                mc.Elapsed+=delegate(object source,EventArgs args)
                {
                    Console.WriteLine("anonymous method");
                }

    如下程序使用了他之前定义的MyTimerClass类。

    1)他从两个不同实例注册两个事件处理程序。

    2)注册事件后休眠2秒,这段时间计时器会触发两次事件,两个事件每次都会执行。

    事件移除程序:

    使用-=符合移除事件处理。

    MC.Elapsed-=CA.TimerHandlerA;

    标准事件用法

    事件使用标准模式的跟本是eventhandler委托类型。eventhandler委托类型的声明如下代码所示:

    1)第一个参数用来保存触发事件的对象的引用。由于是object类型,所以可以匹配任何类型的实例。

    2)第二个参数保存有关状态用于应用程序来说是否合适的状态信息。

    public delegate void eventhandler(object  sender,eventargs e);

    eventargs用于传递数据,但是被设计成不能传递任何数据。  

    如果你希望传递数据,必须设计一个eventargs继承的类。使用合适的字段保存需要传递的数据。

    通过扩展eventargs 来传递数据。

    我们需要 声明一个派生自eventArgs的自定义类。类的名称应该以EventArgs结尾

     public class MyTCEventArgs : EventArgs
        {
            public string Message;
            public MyTCEventArgs(string s)
            {
                Message = s;
            }
        }

    使用自定义委托

    既然有了一个自定义类,就可以传递数据了。我们需要一个委托类型来使用新的自定义类。实现方式如下:

    第一种方式是非泛型委托:

    1)创建一个自定义委托。

    2)在代码的其他部分使用新的委托名称。

    public delegate void MyTCEventHandler object sender,MyTCEventArgs e);
                自定义委托名               自定义类

    第二种方式是泛型委托:

    1)在方括号中放置自定义类。

    2)无论哪里使用自定义委托名称,都使用完整的字符串。例如,event声明是这样的:

     public event EventHandler<MyTCEventArgs> Elapsed;
              自定义类的泛型委托      事件名

    如下是一种泛型委托实现例子:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    
    namespace ConsoleApplication5
    {
        public class MyTCEventArgs : EventArgs  //自定义类声明
        {
            public string Message;
            public MyTCEventArgs(string s)
            {
                Message = s;
            }
        }
        public class MyTimerClass           //事件声明及发起事件的代码
        {
            public event EventHandler<MyTCEventArgs> Elapsed;   //使用泛型委托声明事件
            private void OnOneSecond(object obj, EventArgs e)
            {
                if (Elapsed != null)
                {
                    MyTCEventArgs mtcea= 
                    new MyTCEventArgs("Message from Onesecond");
                    Elapsed(obj, mtcea); //因为事件是EventHandler<MyTCEventArgs>声明的,而EventHandler<MyTCEventArgs>是一个委托类型,所以Elapsed的参数个数跟EventHandler<MyTCEventArgs>一样,
                    //转到定义可以看到 public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e);有两个参数,所以事件Elapsed也有两个参数,且相互对应。               
                }
            }
        }
        class classA                //事件处理程序
        {
            public void TimerHandlerA(Object obj, MyTCEventArgs e)
            {
                Console.WriteLine("classA message {0}", e.Message);
            }
        }
        class Program
        {
            static void Main(string[] args)
            {
                classA ca = new classA();
                MyTimerClass mc = new MyTimerClass();
    
                mc.Elapsed += new EventHandler<MyTCEventArgs>(ca.TimerHandlerA);    //事件注册程序
    
                Thread.Sleep(3500);
    
                Console.ReadLine();
            }
        }
    }

     这里的OnOneSecond()方法是System.Timer类的方法,会自动隔一段时间被触发运行一次。

  • 相关阅读:
    【BZOJ5302】[HAOI2018]奇怪的背包(动态规划,容斥原理)
    【BZOJ5303】[HAOI2018]反色游戏(Tarjan,线性基)
    【BZOJ5304】[HAOI2018]字串覆盖(后缀数组,主席树,倍增)
    【BZOJ5305】[HAOI2018]苹果树(组合计数)
    【BZOJ5300】[CQOI2018]九连环 (高精度,FFT)
    【BZOJ5292】[BJOI2018]治疗之雨(高斯消元)
    【BZOJ5298】[CQOI2018]交错序列(动态规划,矩阵快速幂)
    【BZOJ5289】[HNOI2018]排列(贪心)
    Codeforces Round #539 Div1 题解
    【BZOJ5288】[HNOI2018]游戏(拓扑排序)
  • 原文地址:https://www.cnblogs.com/alsf/p/5942352.html
Copyright © 2011-2022 走看看