您的位置:首页精文荟萃软件资讯 → 浅析C#的事件处理和自定义事件

浅析C#的事件处理和自定义事件

时间:2004/10/8 13:16:00来源:本站整理作者:蓝点我要评论(0)

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


    在写代码前我们先来熟悉.net框架中和事件有关的类和委托,了解C#中预定义事件的处理。


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


    EventHandler是一个委托声明如下


         public delegate void EventHandler( object sender , EventArgs e )


    注意这里的参数,前者是一个对象(其实这里传递的是对象的引用,如果是button1的click事件则sender就是button1),后面是包含事件数据的类的基类。


    下面我们研究一下Button类看看其中的事件声明(使用WinCV工具查看),以Click事件为例。


         public event EventHandler Click;


    这里定义了一个EventHandler类型的事件Click


    前面的内容都是C#在类库中已经为我们定义好了的。下面我们来看编程时产生的代码。


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


    这是我们和button1_click事件所对应的方法。注意方法的参数符合委托中的签名(既参数列表)。那我们怎么把这个方法和事件联系起来呢,请看下面的代码。


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


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


    下面我们研究一下C#事件处理的工作流程,首先系统会在为我们创建一个在后台监听事件的对象(如果是button1的事件那么监听事件的就是button1),这个对象用来产生事件,如果有某个用户事件发生则产生对应的应用程序事件,然后执行订阅了事件的所有方法。


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


    首先我们需要定义一个类来监听客户端事件,这里我们监听键盘的输入。


    定义一个委托。


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


    前面的object用来传递事件的发生者,后面的EventArgs用来传递事件的细节,现在暂时没什么用处,一会后面的例子中将使用。


    下面定义一个此委托类型类型的事件


        public event UserRequest OnUserRequest;


    下面我们来做一个死循环


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


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


   下面我们要做的是定义客户端的类
    首先得实例化UserInputMonitor类
       UserInputMonitor monitor=new UserInputMonitor();


    然后我们定义一个方法。


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


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


     }


     下面创建客户端的实例。


         new Client(monitor);


     对了,别忘了让monitor开始监听事件。


        monitor.run();


     大功告成,代码如下:


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);  //注意这种写法是错误的,因为委托是静态的 }}
三、进一步研究C#中的预定义事件处理机制


    可能大家发现在C#中有些事件和前面的似乎不太一样。例如


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


      }


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


    这里使用了KeyPressEventArgs而不是EventArgs作为参数。这里使用了KeyEventHandler委托,而不是EventHandler委托。


    KeyPressEventArgs是EventArgs的派生类,而KeyEventHandler的声明如下


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


   是参数为KeyEventArgs的委托。那为什么KeyPress事件要这么做呢,我们可以从两个类的构造函数来找答案。


       public EventArgs();


       public KeyPressEventArgs(char keyChar);


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


    我在KeyEventArgs中又发现了属性


       public char KeyChar { get; }


    进一步证明了我的理论。下面我们来做一个类似的例子来帮助理解。


四、简单的自定义事件(2)


    拿我们上面做的例子来改。


    我们也定义一个EventArgs(类似KeyEventArgs)取名MyEventArgs,定义一个构造函数public MyEventArgs(char keyChar),同样我们也设置相应的属性。代码如下


using System;class MyMyEventArgs:EventArgs{ private char keyChar; public MyMyEventArgs(char keyChar) {  this.keychar=keychar; } public char KeyChar {  get  {   return keyChar;  } }}


因为现在要监听多个键了,我们得改写监听器的类中的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);  //注意这种写法是错误的,因为委托是静态的 }}
 


本人水平有限,所以错误难免,极其欢迎大家批评指正。


renrenqq(ddlly)     EMail: ddlly@tom.com,    QQ24008122


相关阅读 Windows错误代码大全 Windows错误代码查询激活windows有什么用Mac QQ和Windows QQ聊天记录怎么合并 Mac QQ和Windows QQ聊天记录Windows 10自动更新怎么关闭 如何关闭Windows 10自动更新windows 10 rs4快速预览版17017下载错误问题Win10秋季创意者更新16291更新了什么 win10 16291更新内容windows10秋季创意者更新时间 windows10秋季创意者更新内容kb3150513补丁更新了什么 Windows 10补丁kb3150513是什么

文章评论
发表评论

热门文章 360快剪辑怎么使用 36金山词霸如何屏幕取词百度收购PPS已敲定!3

最新文章 微信3.6.0测试版更新了微信支付漏洞会造成哪 360快剪辑怎么使用 360快剪辑软件使用方法介酷骑单车是什么 酷骑单车有什么用Apple pay与支付宝有什么区别 Apple pay与贝贝特卖是正品吗 贝贝特卖网可靠吗

人气排行 xp系统停止服务怎么办?xp系统升级win7系统方电脑闹钟怎么设置 win7电脑闹钟怎么设置office2013安装教程图解:手把手教你安装与qq影音闪退怎么办 QQ影音闪退解决方法VeryCD镜像网站逐个数,电驴资料库全集同步推是什么?同步推使用方法介绍QQ2012什么时候出 最新版下载EDiary——一款好用的电子日记本