您的位置:新葡亰496net > 奥门新萄京娱乐场 > 职业事件情势

职业事件情势

发布时间:2019-09-22 11:04编辑:奥门新萄京娱乐场浏览(77)

    .NET框架为事件定义了二个标准方式,它的指标是维持框架和客商代码之间的一致性。

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

     事件,作者信任开始学C#的爱人都会用过,在C#中很宽泛,举例点击二个按键,上传一张图纸等等,在WinForm或WebForm中都在选择着事件。明日,趁着有少少事件,笔者决定来再三一下事先被本人略过的东西

    一、了解C#中的预约义事件处理机制

    行业内部事件的方式为主是System伊夫ntArgs——预约义的未有成员的框架类(不相同于静态Empty属性)

         在写代码前大家先来熟习.net框架春天事件有关的类和嘱托,理解C#中预定义事件的管理。

    • 事件。

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

        在写代码前大家先来熟谙.net框架二月事件有关的类和嘱托,精晓C#中预约义事件的管理。

    EventArgs表示满含事件数量的类的基类,并提供用于不分包事件数量的平地风波的值。用于为事件传递音讯的基类。

         EventArgs是包罗事件数量的类的基类,用于传递事件的细节。

      好记得在头里,在用多个方式的时候,假设参数里面有个Handler,就好恐怖,其实事件依旧用委托来做中介的,在事变上一回转到定义就去到委托了,将委托复制出来,去掉delegate就是方法签字了,写上和煦要兑现的代码给事件赋值就OK了。

        在写代码前大家先来熟稔.net框架二月事件有关的类和委托,通晓C#中预约义事件的拍卖。

        EventArgs是带有事件数量的类的基类,用于传递事件的细节。

    在上边例子中,大家定义EventArgs的子类,用于事件PriceChanged被抓住时,传递新旧Price值:

         EventHandler是四个信托注明如下

      一、什么是事件

        EventArgs是带有事件数量的类的基类,用于传递事件的细节。

        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 )

      事件波及两类角色:事件的发表者和事件的订阅者。触发事件的目的称为事件发表者,捕获时间并对其作出响应的对象叫做事件订阅者。

        EventHandler是一个寄托评释如下

             public delegate void EventHandler( object sender , EventArgs e )

    思考到复用性,EventArgs子类依据它包括的内容命名(而非依照将被应用的风云命名)。

         注意这里的参数,后面一个是三个指标(其实这里传递的是目标的援引,假若是button1的click事件则sender正是button1),后面是满含事件数量的类的基类。

      二、事件和寄托的涉嫌

             public delegate void EventHandler( object sender , EventArgs e )

        注意这里的参数,后面一个是三个目的(其实这里传递的是目的的引用,借使是button1的click事件则sender正是button1),前边是带有事件数量的类的基类。

    选拔或概念事件的嘱托,需遵循三条规范:

         上边大家研讨一下Button类看看里面包车型地铁风波申明(使用WinCV工具查看),以Click事件为例。

      在事变触发现在,事件揭橥者要求揭露音讯,文告事件订阅者实行事件管理,但事件揭橥者并不知道要通报什么事件订阅者,那就需求在宣布者和订阅者之间存在几个中介,那当中介正是委托。大家精通,委托都有三个调用列表,那么,只须要事件公布者有如此四个寄托,各样事件订阅者将协和的事件管理程序都投入到该信托的调用列表中,那么事件触发时,发布者只供给调用委托就能够触发订阅者的事件管理程序。

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

        上边大家商讨一下Button类看看里面的风云申明(使用WinCV工具查看),以Click事件为例。

    • 信托必需以void作为再次来到值
    • 职业事件情势。信托必得承受八个参数:第四个是object类,第三个是伊芙ntArgs的子类。
    • 信托的称呼必需以EventHandler结尾

              public event EventHandler Click;

      三、怎么着评释事件

        上边大家琢磨一下Button类看看在那之中的风云表明(使用WinCV工具查看),以Click事件为例。

             public event EventHandler Click;

     

         这里定义了三个EventHandler类型的平地风波Click

      证明事件的语法和定义二个类的分子非常相像,也极度轻易。事实上,事件便是类成员的一种,只是事件定义中隐含一种奇特的严重性字:event。

             public event EventHandler Click;

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

    完整例子:

         前边的剧情都以C#在类库中已经为大家定义好了的。下边大家来看编制程序时发出的代码。

      事件的申明有三种形式:

        这里定义了二个EventHandler类型的平地风波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)
             {
                 ...
             }

      1、选择自定义委托项目。

        前边的剧情都以C#在类库中已经为大家定义好了的。下边大家来看编制程序时发出的代码。

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

     

         那是大家和button1_click事件所对应的主意。注意情势的参数符合委托中的具名(既参数列表)。那大家怎么把那些措施和事件联系起来呢,请看上边包车型地铁代码。

      2、选拔伊芙ntHandler预约义委托类型。

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

        这是大家和button1_click事件所对应的主意。注意格局的参数符合委托中的签字(既参数列表)。那我们怎么把这些法子和事件联系起来吧,请看上面的代码。

    假若事件不传递额外的消息,能够动用预订义的非泛化委托伊夫ntHandler。如下所示:

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

      这两种办法基本同样,只可是第二种是.Net Framework中分布运用的一种情势,因而建议尽量使用第二种方法。

        那是大家和button1_click事件所对应的办法。注意方法的参数符合委托中的具名(既参数列表)。那我们怎么把这么些主意和事件联系起来吧,请看上边包车型地铁代码。

            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.button1.Click事件。

        //     关键字  委托类型     时间名
        public event  EventHandler PrintComplete;
    

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

        把this.button1_Click方法绑定到this.button1.Click风云。

     

         上边我们钻探一下C#事件管理的干活流程,首先系统会在为大家创制三个在后台监听事件的目的(假如是 button1的轩然大波那么监听事件的正是button1),那些目的用来发惹事件,假使有有些顾客事件爆发则发出相应的应用程序事件,然后实践订阅了轩然大波的富有办法。

      EventHandler是在BCL中预订义的寄托项目,它身处System命名空间,用以管理不包蕴事件数量的事件。事件一旦急需满含事件数量,可以经过派生伊夫ntArgs落成。

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

        下边我们研商一下C#事件管理的做事流程,首先系统会在为我们创设三个在后台监听事件的靶子(如若是 button1的事件那么监听事件的就是button1),那些指标用来产闹事件,固然有有些顾客事件时有产生则发出相应的应用程序事件,然后实践订阅了事件 的具有办法。

    注意:

    二、轻便的自定义事件(1)

      先来探访伊芙ntHandler委托的签订协议:

        下边大家探究一下C#事件管理的行事流程,首先系统会在为大家创立二个在后台监听事件的目的(即使是 button1的风波那么监听事件的正是button1),那么些目的用来发惹祸件,假设有有些用户事件产生则发出相应的应用程序事件,然后施行订阅了轩然大波的全数办法。

    二、简单的自定义事件(1)

    上边例子中事件除了传递已爆发消息,未有传递其余音信。

         首先大家需求定义贰个类来监听顾客端事件,这里我们监听键盘的输入。

    public delegate void EventHandler(Object sender,EventArgs e);
    

    二、轻便的自定义事件(1)

        首先大家须求定义三个类来监听客商端事件,这里我们监听键盘的输入。

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

         定义二个委托。

      1、委托的归来类型为void;

        首先咱们需求定义三个类来监听客商端事件,这里我们监听键盘的输入。

        定义多少个委托。

    职业事件情势。为了防止对伊夫ntArgs不须求的初叶化,提议使用伊芙ntArgs.Empty属性。使用那样五个“空的”静态引用的对象,制止多余地去创建三个新目的。

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

      2、第四个参数--sender参数,它负担保存触发事件的对象的引用,因为参数的类型是Object类型,由此它能够保存任何类型的实例;

        定义八个委托。

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

     

         前边的object用来传递事件的发生者,后边的伊夫ntArgs用来传递事件的内部原因,今后权且没什么用处,一会前边的事例司令员使用。

      3、第三个参数--e参数,它担当保存事件数量,这里是在BCL中定义的暗中认可的EventArgs类,它位于System命名空间中,他无法保留任何数据。

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

        后边的object用来传递事件的爆发者,前面包车型地铁伊芙ntArgs用来传递事件的细节,今后暂且没什么用处,一会后头的例证上校使用。

    微软的大非常多控件所抛出的事件都有多少个参数,第多个是 object 类型的,第三个是 伊夫ntArgs 类型的。

         上面定义一个此委托项目类型的风云

      四、订阅事件

        前边的object用来传递事件的爆发者,前面包车型客车伊芙ntArgs用来传递事件的内部意况,以后近期没什么用处,一会后头的事例中将使用。

        上面定义一个此委托项目类型的事件

    新葡亰496net 1

             public event UserRequest OnUserRequest;

      事件订阅者脚色需求订阅事件发表者发表的平地风波,那样技术在事变揭破时接受到新闻并作出响应,事件实际是信托项目,由这件事件处理方法必得和嘱托签字相相配。要是事件选用预订义的信托项目:伊芙ntHandler,那么相称它的事件管理方法如下:

        上面定义多少个此委托项目类型的平地风波

            public event UserRequest OnUserRequest;

    你从EventArgs  e这里得不到任何此番风云有关需求传递的新闻,真正传递的新闻都在sender中。

         上面大家来做八个死循环

        public void SomeEventHandler(object sender, EventArgs e)
        { 
            //..
        }
    

            public event UserRequest OnUserRequest;

        下边大家来做一个死循环

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

      有了事件管理方法,就能够订阅事件了,只须要利用加法赋值运算符( =)就可以。

        上面大家来做四个死循环

     1新葡亰496net 2   public void Run()
     2新葡亰496net 3新葡亰496net 4     新葡亰496net 5{
     3新葡亰496net 6    bool finished=false;
     4新葡亰496net 7    do
     5新葡亰496net 8新葡亰496net 9    新葡亰496net 10{
     6新葡亰496net 11     if (Console.ReadLine()=="h")
     7新葡亰496net 12新葡亰496net 13    新葡亰496net 14{
     8新葡亰496net 15    OnUserRequest(this,new EventArgs());
     9新葡亰496net 16    }  
    10新葡亰496net 17    }while(!finished);
    11新葡亰496net 18     }

         此代码不断的要求顾客输入字符,若是输入的结果是h,则触发OnUserRequest事件,事件的触发者是本人(this),事件细节无(未有传递任何参数的伊夫ntArgs实例)。大家给这一个类取名称叫UserInputMonitor。

      五、触发事件

     

       此代码不断的渴求客户输入字符,假若输入的结果是h,则触发OnUserRequest事件,事件的触发者是本人(this),事件细节无(没有传递任何参数的EventArgs实例)。大家给那么些类取名字为UserInputMonitor。

        下面我们要做的是定义客户端的类
         首先得实例化UserInputMonitor类
    
        //检查事件是否为空
        if (PrintComplete != null)
        { 
            //像调用方法一样触发事件,参数
            PrintComplete(this,new EventArgs();
        }
    

     1新葡亰496net 19   public void Run()
     2新葡亰496net 20     {
     3新葡亰496net 21    bool finished=false;
     4新葡亰496net 22    do
     5新葡亰496net 23    {
     6新葡亰496net 24     if (Console.ReadLine()=="h")
     7新葡亰496net 25    {
     8新葡亰496net 26    OnUserRequest(this,new EventArgs());
     9新葡亰496net 27    }  
    10新葡亰496net 28    }while(!finished);
    11新葡亰496net 29     }

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

            UserInputMonitor monitor=new UserInputMonitor();

      完整的二个事变例子:

       此代码不断的渴求客户输入字符,假诺输入的结果是h,则触发OnUserRequest事件,事件的触发者是自个儿(this),事件细节无(没有传递任何参数的EventArgs实例)。我们给这一个类取名字为UserInputMonitor。

           UserInputMonitor monitor=new UserInputMonitor();

         然后我们定义三个方法。

    新葡亰496net 30

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

        然后大家定义多个主意。

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

    namespace ConsoleApplication1
    {
        public class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("该做的东西做完,然后触发事件!");
                EventSample es = new EventSample();
                es.ShowComplete  = es.MyEventHandler;
                es.OnShowComplete();
    
                Console.ReadKey();
            }
        }
    
        public class EventSample
        {
         //定义一个事件
            public event EventHandler ShowComplete;
        
         //触发事件
            public void OnShowComplete()
            {
                //判断是否绑定了事件处理方法,null表示没有事件处理方法
                if (ShowComplete != null)
                {
              //像调用方法一样触发事件
                    ShowComplete(this, new EventArgs());
                }
            }
    
            //事件处理方法
            public void MyEventHandler(object sender, EventArgs e)
            {
                Console.WriteLine("谁触发了我?"   sender.ToString());
            }
        }
    }
    

           UserInputMonitor monitor=new UserInputMonitor();

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

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

    新葡亰496net 31

        然后大家定义叁个艺术。

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

         Client(UserInputMonitor m)
          {
           m.OnUserRequest =new UserInputMonitor.UserRequest(this.ShowMessage);
           //m.OnUserRequest =new m.UserRequest(this.ShowMessage);

      六、使用和增加EventArgs类

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

         Client(UserInputMonitor m)
         {
          m.OnUserRequest =new UserInputMonitor.UserRequest(this.ShowMessage);
          //m.OnUserRequest =new m.UserRequest(this.ShowMessage);

           //注意这种写法是荒谬的,因为委托是静态的

      前边提到过,默许的约定义委托EventHandler的第一个参数,本身无法包含事件数量。但是在相当多.net提供的法子,都能用e调用出一些音信那是因为那不是默许的EventArgs类了。由此,在事件引发时不可能向事件管理程序传递状态消息,倘若要想传递状态消息,则要求从此类派生出三个类来保存新闻。

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

          //注意这种写法是漏洞比很多的,因为委托是静态的

          }

      以下为增添EventArgs类的亲自过问:

         Client(UserInputMonitor m)
         {
          m.OnUserRequest =new UserInputMonitor.UserRequest(this.ShowMessage);
          //m.OnUserRequest =new m.UserRequest(this.ShowMessage);

         }

          上边创设顾客端的实例。

    新葡亰496net 32

          //注意这种写法是一无所长的,因为委托是静态的

         下边创造顾客端的实例。

            new Client(monitor);

        public class PrintEventArgs : EventArgs
        {
            public string PrintState
            {
                get;
                set;
            }
    
            public PrintEventArgs(string state)
            {
                PrintState = state;
            }
        }
    

         }

             new Client(monitor);

          对了,别忘了让monitor早先监听事件。

    新葡亰496net 33

         上边创制客商端的实例。

         对了,别忘了让monitor最初监听事件。

             monitor.run();

      而在调用时,只需将EventArgs换到PrintEventArgs

             new Client(monitor);

            monitor.run();

          马到成功,代码如下:

        public void SomeEventHandler(object sender, PrintEventArgs e)
        {
            Console.WriteLine("打印已完成!");
        }
    

         对了,别忘了让monitor初步监听事件。

         马到功成,代码如下:

    using System;
    class UserInputMonitor
    {
     public delegate void UserRequest(object sender,EventArgs e);
     //定义委托
     public event UserRequest OnUserRequest;
     //此委托类型类型的事件
     public void Run()
     {
      bool finished=false;
      do
      {
       if (Console.ReadLine()=="h")
       {
        OnUserRequest(this,new EventArgs());
       }  
      }while(!finished);
     }
    }
    
    public class Client
    {
     public static void Main()
     {
      UserInputMonitor monitor=new UserInputMonitor();
      new Client(monitor);
      monitor.Run();
     }
     private void ShowMessage(object sender,EventArgs e)
     {
      Console.WriteLine("HaHa!!");
     }
     Client(UserInputMonitor m)
     {
      m.OnUserRequest =new UserInputMonitor.UserRequest(this.ShowMessage);
      //m.OnUserRequest =new m.UserRequest(this.ShowMessage);
      //注意这种写法是错误的,因为委托是静态的
     }
    }
    

      但是要专一此时,绑定事件编写翻译器会报错:

            monitor.run();

     1新葡亰496net 34using System;
     2新葡亰496net 35class UserInputMonitor
     3新葡亰496net 36新葡亰496net 37新葡亰496net 38{
     4新葡亰496net 39public delegate void UserRequest(object sender,EventArgs e);
     5新葡亰496net 40//定义委托
     6新葡亰496net 41public event UserRequest OnUserRequest;
     7新葡亰496net 42//此委托项目类型的平地风波
     8新葡亰496net 43public void Run()
     9新葡亰496net 44新葡亰496net 45新葡亰496net 46{
    10新葡亰496net 47bool finished=false;
    11新葡亰496net 48do
    12新葡亰496net 49新葡亰496net 50新葡亰496net 51{
    13新葡亰496net 52if (Console.ReadLine()=="h")
    14新葡亰496net 53新葡亰496net 54新葡亰496net 55{
    15新葡亰496net 56OnUserRequest(this,new EventArgs());
    16新葡亰496net 57}  
    17新葡亰496net 58}while(!finished);
    18新葡亰496net 59}
    19新葡亰496net 60}
    20新葡亰496net 61
    21新葡亰496net 62public class Client
    22新葡亰496net 63新葡亰496net 64新葡亰496net 65{
    23新葡亰496net 66public static void Main()
    24新葡亰496net 67新葡亰496net 68新葡亰496net 69{
    25新葡亰496net 70UserInputMonitor monitor=new UserInputMonitor();
    26新葡亰496net 71new Client(monitor);
    27新葡亰496net 72monitor.Run();
    28新葡亰496net 73}
    29新葡亰496net 74private void ShowMessage(object sender,EventArgs e)
    30新葡亰496net 75新葡亰496net 76新葡亰496net 77{
    31新葡亰496net 78Console.WriteLine("HaHa!!");
    32新葡亰496net 79}
    33新葡亰496net 80Client(UserInputMonitor m)
    34新葡亰496net 81新葡亰496net 82新葡亰496net 83{
    35新葡亰496net 84m.OnUserRequest =new UserInputMonitor.UserRequest(this.ShowMessage);
    36新葡亰496net 85//m.OnUserRequest =new m.UserRequest(this.ShowMessage);
    37新葡亰496net 86//注意这种写法是大错特错的,因为委托是静态的
    38新葡亰496net 87}
    39新葡亰496net 88}
    40新葡亰496net 89

    三、进一步商量C#中的预订义事件管理机制

      enentSample.PrintComplete  = ShowMessage;  //此行代码编译器报错
    

         水到渠成,代码如下:

    三、进一步研究C#中的预约义事件管理机制

         大概大家开采在C#中多少事件和前边的仿佛不太一致。比方

      为何吧?因而事件委托的第二个参数是伊芙ntArgs类型与强大的PrintEventArgs区别,由此无法在绑定旧的秘诀;所以将在选择自定义委托了。

     

        或然大家发掘在C#中多少事件和前边的就像不太一致。比如

           private void textBox1_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
           {

      七、自定义委托

     1新葡亰496net 90using System;
     2新葡亰496net 91class UserInputMonitor
     3新葡亰496net 92{
     4新葡亰496net 93public delegate void UserRequest(object sender,EventArgs e);
     5新葡亰496net 94//定义委托
     6新葡亰496net 95public event UserRequest OnUserRequest;
     7新葡亰496net 96//此委托项目类型的平地风波
     8新葡亰496net 97public void Run()
     9新葡亰496net 98{
    10新葡亰496net 99bool finished=false;
    11新葡亰496net 100do
    12新葡亰496net 101{
    13新葡亰496net 102if (Console.ReadLine()=="h")
    14新葡亰496net 103{
    15新葡亰496net 104OnUserRequest(this,new EventArgs());
    16新葡亰496net 105}  
    17新葡亰496net 106}while(!finished);
    18新葡亰496net 107}
    19新葡亰496net 108}
    20新葡亰496net 109
    21新葡亰496net 110public class Client
    22新葡亰496net 111{
    23新葡亰496net 112public static void Main()
    24新葡亰496net 113{
    25新葡亰496net 114UserInputMonitor monitor=new UserInputMonitor();
    26新葡亰496net 115new Client(monitor);
    27新葡亰496net 116monitor.Run();
    28新葡亰496net 117}
    29新葡亰496net 118private void ShowMessage(object sender,EventArgs e)
    30新葡亰496net 119{
    31新葡亰496net 120Console.WriteLine("HaHa!!");
    32新葡亰496net 121}
    33新葡亰496net 122Client(UserInputMonitor m)
    34新葡亰496net 123{
    35新葡亰496net 124m.OnUserRequest =new UserInputMonitor.UserRequest(this.ShowMessage);
    36新葡亰496net 125//m.OnUserRequest =new m.UserRequest(this.ShowMessage);
    37新葡亰496net 126//注意这种写法是不当的,因为委托是静态的
    38新葡亰496net 127}
    39新葡亰496net 128}
    40新葡亰496net 129

          private void textBox1_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
          {

           }

      既然伊芙ntHandler委托无法使用了,那么就只有思索采用自定义委托来声称事件了。首先声雅培(Abbott)个自定义委托:

     

          }

           this.textBox1.KeyPress =newSystem.Windows.Forms.KeyPressEventHandler(this.textBox1_KeyPress);

      public delegate void PrintEventDelegate(object sender,PrintEventArgs e);
    

    三、进一步研商C#中的预订义事件管理机制

          this.textBox1.KeyPress =newSystem.Windows.Forms.KeyPressEventHandler(this.textBox1_KeyPress);

         这里运用了KeyPressEventArgs并非EventArgs作为参数。这里运用了Key伊夫ntHandler委托,并非EventHandler委托。

      接下去,将事件申明中运用的预订义委托EventDelegate换到大家自定义的嘱托:

        恐怕我们开采在C#中稍微事件和前边的就如不太一致。举个例子

        这里运用了KeyPressEventArgs并非伊芙ntArgs作为参数。这里运用了KeyEventHandler委托,实际不是EventHandler委托。

        KeyPressEventArgs是EventArgs的派生类,而Key伊芙ntHandler的注脚如下

      public event PrintEventDelegate PrintComplete;
    

          private void textBox1_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
          {

        KeyPressEventArgs是EventArgs的派生类,而Key伊芙ntHandler的评释如下

           public delegate void KeyEventHandler( object sender , KeyEventArgs e );

      因为大家增加的Print伊芙ntArgs类未有不带参数的构造函数,由此须求修改事件触发部分的代码,传递多个参数进去,该参数的值正是要发送给事件管理方法的情事音信,这里以多少个简易的字符串取代:

          }

          public delegate void KeyEventHandler( object sender , KeyEventArgs e );

        是参数为Key伊夫ntArgs的信托。这为啥KeyPress事件要这么做啊,大家得以从五个类的构造函数来找答案。

      if(PrintComplete != null)
      {
        PrintComplete(this,new PrintEventArgs("测试消息"));
      }
    

          this.textBox1.KeyPress =newSystem.Windows.Forms.KeyPressEventHandler(this.textBox1_KeyPress);

       是参数为Key伊芙ntArgs的寄托。那为啥KeyPress事件要那样做吗,我们能够从八个类的构造函数来找答案。

           public EventArgs();

      八、事件访谈器

        这里运用了KeyPress伊芙ntArgs并不是EventArgs作为参数。这里运用了KeyEventHandler委托,并不是EventHandler委托。

           public EventArgs();

           public KeyPressEventArgs(char keyChar);

      事件是与众不一样的多路广播委托,事件暗许有一个私人民居房的委托项目变量,用以保存对订阅事件的事件管理方法的援用,此委托项指标变量仅能从注明该事件的类中央委员托。事件订阅者通过提供对事件管理方法的引用来订阅事件,这个格局通过私下认可的年华访问器增加到委托的调用列表中。这里的风云访问器类似于属性访谈器,分歧之处在于,时间访谈器被取名称叫add和remove,并不是性质的get和set。在相当多状态下都无需提供自定义的风浪访谈器。若无提供,则编译器会自行抬高事件访问器。假设须求增添自定义事件访谈器,以支撑有个别自定义行为,能够运用如下语法:

        KeyPress伊芙ntArgs是EventArgs的派生类,而KeyEventHandler的扬言如下

           public KeyPressEventArgs(char keyChar);

         这里的keyData是什么样,是用来传递大家按下了哪个键的,哈。

    新葡亰496net 130

          public delegate void KeyEventHandler( object sender **KeyEventArgs );**

        这里的keyData是何等,是用来传递我们按下了哪个键的,哈。

         作者在Key伊芙ntArgs中又挖掘了品质

      public event MyEventHandler PrintComplete
      {
        add
        {
          //..
        }
        remove
        {
          //..
        }
      }
    

       是参数为KeyEventArgs的嘱托。那干什么KeyPress事件要这么做吧,大家可以从两个类的构造函数来找答案。

        小编在KeyEventArgs中又发掘了质量

            public char KeyChar { get; }

    新葡亰496net 131

           public EventArgs();

           public char KeyChar { get; }

         进一步验证了本人的反驳。上面大家来做叁个近乎的事例来扶持驾驭。

      在申明了风波访谈器现在,编写翻译器将不会提供个人的信托对象,此时对此订阅者事件管理方法援引的保管亟待大家友好去贯彻。

           public KeyPressEventArgs(char keyChar);

        进一步证实了自家的论战。下边我们来做一个看似的例证来增援理解。

    四、轻巧的自定义事件(2)

        public event MyEventHandler PrintComplete
        {
            add { myEventHandler  = value; }
            remove { myEventHandler -= value; }
        }
    

        这里的keyData是什么样,是用来传递大家按下了哪个键的,哈。

    四、轻便的自定义事件(2)

        拿大家地点做的例证来改。

       上边给出二个扩展伊夫ntArgs与自定义委托,传递数据到情势的示范:

        笔者在KeyEventArgs中又发掘了质量

        拿大家地点做的例证来改。

         我们也定义三个伊芙ntArgs(类似KeyEventArgs)取名MyEventArgs,定义一个构造函数public My伊芙ntArgs(char keyChar),同样大家也安装相应的品质。代码如下

    新葡亰496net 132

           public char KeyChar { get; }

        大家也定义叁个EventArgs(类似Key伊芙ntArgs)取名My伊夫ntArgs,定义二个结构函数public My伊夫ntArgs(char keyChar),同样大家也安装相应的性质。代码如下

    using System;
    class MyMyEventArgs:EventArgs
    {
     private char keyChar;
     public MyMyEventArgs(char keyChar)
     {
      this.keychar=keychar;
     }
     public char KeyChar
     {
      get
      {
       return keyChar;
      }
     }
    }
    
    namespace ConsoleApplication1
    {
        public class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("该做的东西做完,然后触发事件!");
                EventSample es = new EventSample();
                es.ShowComplete  = es.MyEventHandler;
                es.OnShowComplete();
    
                Console.ReadKey();
            }
        }
    
        public class EventSample
        {
            //此事件已不能如此使用
            //public event EventHandler ShowComplete;
    
            //自定义委托
            public delegate void ShowEventDelegate(object sender,ShowEventArgs e);
    
            //将事件中的委托换成自己的自定义委托
            public event ShowEventDelegate ShowComplete; 
    
            public void OnShowComplete()
            {
                //判断是否绑定了事件处理方法,null表示没有事件处理方法
                if (ShowComplete != null)
                {
                    //这次要传递参数数据了
                    ShowComplete(this, new ShowEventArgs("传给你的数据,接着吧!"));
                }
            }
    
            //事件处理方法,注意第二个参数
            public void MyEventHandler(object sender, ShowEventArgs e)
            {
                Console.WriteLine("谁触发了我   "   sender.ToString());
                Console.WriteLine("传过来什么数据:   "   e.ShowResult);
            }
        }
    
        //自定义EventArgs
        public class ShowEventArgs : EventArgs
        {
            public string ShowResult
            {
                get;
                set;
            }
    
            public ShowEventArgs(string result)
            {
                ShowResult = result;
            }
        }
    }
    

        进一步验证了本身的说理。下边我们来做二个近似的例子来扶持通晓。

     1新葡亰496net 133using System;
     2新葡亰496net 134class MyMyEventArgs:EventArgs
     3新葡亰496net 135新葡亰496net 136新葡亰496net 137{
     4新葡亰496net 138private char keyChar;
     5新葡亰496net 139public MyMyEventArgs(char keyChar)
     6新葡亰496net 140新葡亰496net 141新葡亰496net 142{
     7新葡亰496net 143this.keychar=keychar;
     8新葡亰496net 144}
     9新葡亰496net 145public char KeyChar
    10新葡亰496net 146新葡亰496net 147新葡亰496net 148{
    11新葡亰496net 149get
    12新葡亰496net 150新葡亰496net 151新葡亰496net 152{
    13新葡亰496net 153return keyChar;
    14新葡亰496net 154}
    15新葡亰496net 155}
    16新葡亰496net 156}
    17新葡亰496net 157
    18新葡亰496net 158

    因为今日要监听多个键了,大家得改写监听器的类中的do...while部分。改写委托,改写客户端传递的参数。好了最后代码如下,好累

    新葡亰496net 159

    四、轻松的自定义事件(2)

    因为未来要监听八个键了,大家得改写监听器的类中的do...while部分。改写委托,改写顾客端传递的参数。好了最后代码如下,好累

    using System;
    class MyEventArgs:EventArgs
    {
     private char keyChar;
     public MyEventArgs(char keyChar)
     {
      this.keyChar=keyChar;
     }
     public char KeyChar
     {
      get
      {
       return keyChar;
      }
     }
    }
    
    class UserInputMonitor
    {
     public delegate void UserRequest(object sender,MyEventArgs e);
     //定义委托
     public event UserRequest OnUserRequest;
     //此委托类型类型的事件
     public void Run()
     {
      bool finished=false;
      do
      {
       string inputString= Console.ReadLine();
       if (inputString!="") 
        OnUserRequest(this,new MyEventArgs(inputString[0]));
      }while(!finished);
     }
    }
    
    public class Client
    {
     public static void Main()
     {
      UserInputMonitor monitor=new UserInputMonitor();
      new Client(monitor);
      monitor.Run();
     }
     private void ShowMessage(object sender,MyEventArgs e)
     {
      Console.WriteLine("捕捉到:{0}",e.KeyChar);
     }
     Client(UserInputMonitor m)
     {
      m.OnUserRequest =new UserInputMonitor.UserRequest(this.ShowMessage);
      //m.OnUserRequest =new m.UserRequest(this.ShowMessage);
      //注意这种写法是错误的,因为委托是静态的
     }
    }
    

      输出结果如下:

        拿我们地点做的事例来改。

     1新葡亰496net 160using System;
     2新葡亰496net 161class MyEventArgs:EventArgs
     3新葡亰496net 162新葡亰496net 163新葡亰496net 164{
     4新葡亰496net 165private char keyChar;
     5新葡亰496net 166public MyEventArgs(char keyChar)
     6新葡亰496net 167新葡亰496net 168新葡亰496net 169{
     7新葡亰496net 170this.keyChar=keyChar;
     8新葡亰496net 171}
     9新葡亰496net 172public char KeyChar
    10新葡亰496net 173新葡亰496net 174新葡亰496net 175{
    11新葡亰496net 176get
    12新葡亰496net 177新葡亰496net 178新葡亰496net 179{
    13新葡亰496net 180return keyChar;
    14新葡亰496net 181}
    15新葡亰496net 182}
    16新葡亰496net 183}
    17新葡亰496net 184
    18新葡亰496net 185class UserInputMonitor
    19新葡亰496net 186新葡亰496net 187新葡亰496net 188{
    20新葡亰496net 189public delegate void UserRequest(object sender,MyEventArgs e);
    21新葡亰496net 190//定义委托
    22新葡亰496net 191public event UserRequest OnUserRequest;
    23新葡亰496net 192//此委托项目类型的风云
    24新葡亰496net 193public void Run()
    25新葡亰496net 194新葡亰496net 195新葡亰496net 196{
    26新葡亰496net 197bool finished=false;
    27新葡亰496net 198do
    28新葡亰496net 199新葡亰496net 200新葡亰496net 201{
    29新葡亰496net 202string inputString= Console.ReadLine();
    30新葡亰496net 203if (inputString!="") 
    31新葡亰496net 204OnUserRequest(this,new MyEventArgs(inputString[0]));
    32新葡亰496net 205}while(!finished);
    33新葡亰496net 206}
    34新葡亰496net 207}
    35新葡亰496net 208
    36新葡亰496net 209
    37新葡亰496net 210public class Client
    38新葡亰496net 211新葡亰496net 212新葡亰496net 213{
    39新葡亰496net 214public static void Main()
    40新葡亰496net 215新葡亰496net 216新葡亰496net 217{
    41新葡亰496net 218UserInputMonitor monitor=new UserInputMonitor();
    42新葡亰496net 219new Client(monitor);
    43新葡亰496net 220monitor.Run();
    44新葡亰496net 221}
    45新葡亰496net 222private void ShowMessage(object sender,MyEventArgs e)
    46新葡亰496net 223新葡亰496net 224新葡亰496net 225{
    47新葡亰496net 226Console.WriteLine("捕捉到:{0}",e.KeyChar);
    48新葡亰496net 227}
    49新葡亰496net 228Client(UserInputMonitor m)
    50新葡亰496net 229新葡亰496net 230新葡亰496net 231{
    51新葡亰496net 232m.OnUserRequest =new UserInputMonitor.UserRequest(this.ShowMessage);
    52新葡亰496net 233//m.OnUserRequest =new m.UserRequest(this.ShowMessage);
    53新葡亰496net 234//注意这种写法是一无可取的,因为委托是静态的
    54新葡亰496net 235}
    55新葡亰496net 236}
    56新葡亰496net 237

      新葡亰496net 238

        我们也定义多少个EventArgs(类似Key伊芙ntArgs)取名MyEventArgs,定义叁个构造函数public MyEventArgs(char keyChar),同样大家也安装相应的特性。代码如下

      九、事件的归纳说明

     

      在事件中,一共有4个至关心尊敬要东西。

     1新葡亰496net 239using System;
     2新葡亰496net 240class MyMyEventArgs:EventArgs
     3新葡亰496net 241{
     4新葡亰496net 242private char keyChar;
     5新葡亰496net 243public MyMyEventArgs(char keyChar)
     6新葡亰496net 244{
     7新葡亰496net 245this.keychar=keychar;
     8新葡亰496net 246}
     9新葡亰496net 247public char KeyChar
    10新葡亰496net 248{
    11新葡亰496net 249get
    12新葡亰496net 250{
    13新葡亰496net 251return keyChar;
    14新葡亰496net 252}
    15新葡亰496net 253}
    16新葡亰496net 254}
    17新葡亰496net 255
    18新葡亰496net 256

    1、sender:传递触发委托的对象;
    2、伊夫ntArgs:传递事件的细节;
    3、EventHandler:用于受托方法;
    4、delegate:方法的卷入,允许将艺术传递过去;

     

      如当点击二个按键时,施行委托(伊芙ntHandler所绑定的法子),并告诉委托程序,是开关1(object sender)被点击(EventArgs e)了。  

    因为以后要监听多少个键了,大家得改写监听器的类中的do...while部分。改写委托,改写客商端传递的参数。好了最终代码如下,好累

      比比较多时候,由于.Net自带的那么些基类不可见满足大家要求传递的多少个参数,所以不常我们要求自定义各个承接类。

     

      举例,大家在Winform上拖入三个文本框,并设置textBox1_MouseClick事件,则转移的代码如下:

     1新葡亰496net 257using System;
     2新葡亰496net 258class MyEventArgs:EventArgs
     3新葡亰496net 259{
     4新葡亰496net 260private char keyChar;
     5新葡亰496net 261public MyEventArgs(char keyChar)
     6新葡亰496net 262{
     7新葡亰496net 263this.keyChar=keyChar;
     8新葡亰496net 264}
     9新葡亰496net 265public char KeyChar
    10新葡亰496net 266{
    11新葡亰496net 267get
    12新葡亰496net 268{
    13新葡亰496net 269return keyChar;
    14新葡亰496net 270}
    15新葡亰496net 271}
    16新葡亰496net 272}
    17新葡亰496net 273
    18新葡亰496net 274class UserInputMonitor
    19新葡亰496net 275{
    20新葡亰496net 276public delegate void UserRequest(object sender,MyEventArgs e);
    21新葡亰496net 277//定义委托
    22新葡亰496net 278public event UserRequest OnUserRequest;
    23新葡亰496net 279//此委托项目类型的事件
    24新葡亰496net 280public void Run()
    25新葡亰496net 281{
    26新葡亰496net 282bool finished=false;
    27新葡亰496net 283do
    28新葡亰496net 284{
    29新葡亰496net 285string inputString= Console.ReadLine();
    30新葡亰496net 286if (inputString新葡亰496net,!="") 
    31新葡亰496net 287OnUserRequest(this,new MyEventArgs(inputString[0]));
    32新葡亰496net 288}while(!finished);
    33新葡亰496net 289}
    34新葡亰496net 290}
    35新葡亰496net 291
    36新葡亰496net 292
    37新葡亰496net 293public class Client
    38新葡亰496net 294{
    39新葡亰496net 295public static void Main()
    40新葡亰496net 296{
    41新葡亰496net 297UserInputMonitor monitor=new UserInputMonitor();
    42新葡亰496net 298new Client(monitor);
    43新葡亰496net 299monitor.Run();
    44新葡亰496net 300}
    45新葡亰496net 301private void ShowMessage(object sender,MyEventArgs e)
    46新葡亰496net 302{
    47新葡亰496net 303Console.WriteLine("捕捉到:{0}",e.KeyChar);
    48新葡亰496net 304}
    49新葡亰496net 305Client(UserInputMonitor m)
    50新葡亰496net 306{
    51新葡亰496net 307m.OnUserRequest =new UserInputMonitor.UserRequest(this.ShowMessage);
    52新葡亰496net 308//m.OnUserRequest =new m.UserRequest(this.ShowMessage);
    53新葡亰496net 309//注意这种写法是错误的,因为委托是静态的
    54新葡亰496net 310}
    55新葡亰496net 311}
    56新葡亰496net 312

    private void textBox1_MouseClick(object sender, MouseEventArgs e)
    {
      Console.WriteLine(e.Clicks);
    }
    

      大家看到原来的EventArgs形成了MouseEventArgs。

      其代码如下,比较之下,它能够传递越多的参数了。

    新葡亰496net 313

        // 摘要: 
        //     为 System.Windows.Forms.Control.MouseUp、System.Windows.Forms.Control.MouseDown
        //     和 System.Windows.Forms.Control.MouseMove 事件提供数据。
        [ComVisible(true)]
        public class MouseEventArgs : EventArgs
        {
            // 摘要: 
            //     初始化 System.Windows.Forms.MouseEventArgs 类的新实例。
            //
            // 参数: 
            //   button:
            //     System.Windows.Forms.MouseButtons 值之一,指示按下的鼠标按钮。
            //
            //   clicks:
            //     鼠标按钮曾被按下的次数。
            //
            //   x:
            //     鼠标单击的 x 坐标(以像素为单位)。
            //
            //   y:
            //     鼠标单击的 y 坐标(以像素为单位)。
            //
            //   delta:
            //     鼠标轮已转动的制动器数的有符号计数。
            public MouseEventArgs(MouseButtons button, int clicks, int x, int y, int delta);
            //     获取曾按下的是哪个鼠标按钮。
            public MouseButtons Button { get; }
            //     获取按下并释放鼠标按钮的次数。
            public int Clicks { get; }
            //     获取鼠标轮已转动的制动器数的有符号计数乘以 WHEEL_DELTA 常数。 制动器是鼠标轮的一个凹口。
            public int Delta { get; }
            //     获取鼠标在产生鼠标事件时的位置。
            public Point Location { get; }
            //     获取鼠标在产生鼠标事件时的 x 坐标。
            public int X { get; }
            //     获取鼠标在产生鼠标事件时的 y 坐标。
            public int Y { get; }
        }
    

    新葡亰496net 314

     

     

      归根结蒂,object sender与伊芙ntArgs e都以为着传递参数。自定义的能够传递越多参数。

     

     

      事件实际应用的德姆o:

     

    转自:

    本文由新葡亰496net发布于奥门新萄京娱乐场,转载请注明出处:职业事件情势

    关键词:

上一篇:python文件操作,文件管理

下一篇:没有了