zoukankan      html  css  js  c++  java
  • 基础系列之---5.C#委托和事件使用(参考)

    用一个例子来说明事件的使用。

    创建一个简单的类,名为FileWatch,包含事件OnfileChange。该类将检查在执行应用程序的目录(当前目录,通常是项目名/bin/debug)下,是否存在文件test.txt。

    如果文件被删除或创建,都将触发事件。同时提供一个方法MonitorFile以不断地查询该文件。

    方法:

    在创建一个可用事件之前,首先声明一个委托,放在类的外面。
    public delegate void FileWatchEventHandler(object sender,EventArgs e);

    接下来创建类FileWatch。然后声明事件,注意事件的类型即为我们之前定义的委托


    public event FileWatchEventHandler FileWatchEvent;

    现在创建方法OnFileChange(),当调用该方法时将触发事件

    protected virtual void OnFileChange(EventArgs e)
    {
         if (FileWatchEvent!=null)
         {
             FileWatchEvent(this,e);
         }
    }

    最后,创建方法MonitorFile(),

    public void MonitorFile()
    {
        bool bCurrentStatus;
       
        while(true)
        {
             bCurrentStatus = File.Exists("test.txt");
             if (bCurrentStatus != _bLastStatus) //_bLastStatus为私有字段,初始值为false;
             {
                 _bLastStatus = bCurrentStatus;
                 OnFileChange(EventArgs.Empty);
             }

             Thread.Sleep(250);
        }
    }

    完整代码如下:

    using System;
    using System.Threading; 
    using System.IO;      

    namespace Sample.Event

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

          public class FileWatch
          {
                private bool _bLastStatus = false;
                public FileWatch()
                {
                      //
                      // TODO: 在此处添加构造函数逻辑
                      //
                } 

                public event FileWatchEventHandler FileWatchEvent; 

                protected virtual void OnFileChange(EventArgs e)
                {
                      if (FileWatchEvent != null)
                      {
                           
                            FileWatchEvent(this, e);
                      }
                } 

                public void MonitorFile()
                {
                      bool bCurrentStatus; 

                      while(true)
                      {
                            bCurrentStatus = File.Exists("test.txt");

                            //状态不符,说明文件被删除或重新创建,此时触发事件;
                            if ( bCurrentStatus != _bLastStatus )
                            {
                                  _bLastStatus = bCurrentStatus;
                                  OnFileChange( EventArgs.Empty );
                            } 

                           
                            Thread.Sleep(250);
                      } 

                }
          }
    }


    使用:创建一个Windows应用程序来测试我们之前建立的FileWatch中的事件。首先将刚才创建的项目编译

    ,生成Assembly:FileWatch.dll,然后添加引用。当然直接添加项目引用也可以。然后在Windows应用程

    序中加入命名空间:

    using Sample.Event;

    然后在应用程序类中,定义一个私有字段,类型为我们之前创建的类FileWatch:
    public class frmMain : System.Windows.Forms.Form
          {
                private Sample.Event.FileWatch FileWatchEventSource;

    并在构造函数中实例化该对象;

    public frmMain()
                {
                     
                      InitializeComponent();
                     

                      FileWatchEventSource = new Sample.Event.FileWatch();

    然后将本地方法OnFileChange连接到事件中:

    FileWatchEventSource.FileWatchEvent+=new Sample.Event.FileWatchEventHandler(OnFileChange);

    我们需要调用MonitorFile方法来触发事件。在本例中,我们用线程来控制MonitorFile方法。这样可以在

    应用程序闲置的时候运行该方法以触发事件。

    thrd = new Thread(new ThreadStart(FileWatchEventSource.MonitorFile));
    thrd.Start();

    最后,我们需要知道事件是否被触发,为了记录下事件触发的历史记录,我们在ListBox控件添加触发内

    容。由于事件触发后调用的方法是OnFileChange,因此我们将操作放在该方法里:

    private void OnFileChange(object Sender, EventArgs e)
    {
       listBox.Items.Add(DateTime.Now.ToString()+": 文件发生改变.");
    }

    当触发事件时,EventHanler会传递sender和EventArgs类的引用。EventArgs类通常是在事件源和触发事

    件器之间传递信息。在本例中,没有传递信息,也没有用到EventArgs类。而只是将事件添加到了ListBox

    中。

    运行结果如下:


     

    结论:在C#中使用事件的要点:

    首先,要建立委托,格式为:
    public delegate void 委托名(object sender, EventArgs e);
    注意:委托即C里的函数指针,在事件中由于要传递事件及触发事件的对象的信息,因此参数表是固定的。委托名一般格式是:名字+EnvenHandle。这样取名比较规范。

    然后,建立一个事件字段:
    public event 委托类型 事件名;
    注意:event关键字代表事件,返回类型为委托;

    再定义一个方法,处理事件,再本例中为OnFileChange(EventArgs e)。在该方法中应该调用事件:
    事件名(object ,EventArgs);
    这里object一般为本身,实参应为this,EventArgs应为OnFileChange中传递过来的实参,尤其是要传递事件的值。

    最后还要创建触发事件的方法。例子中为MonitorFile(),在其方法中,当条件满足则调用OnFileChange来达到触发事件的目的。


    在使用事件时,通常要定义两个方法,一个是和事件定义的委托签名一致的方法,在本例中为OnFileChange(Object sender,EventArgs e);

    注意在例子中,窗体类的OnFileChange和事件类的OnFileChange是不同的。后者用于调用事件,前者则用于绑定事件。绑定事件的方法很简单,用+=表示添加事件,-=表示删除事件。
    例子中
    FileWatchEventSource.FileWatchEvent+=new Sample.Event.FileWatchEventHandler(OnFileChange);
    即为添加事件。

    例子中:首先线程启动(thd.Start()),然后调用MonitorFile()方法。引起事件产生,FileWatchEvent产生后,由于我们将事件FileWatchEvent绑定到了OnFileChange()方法上。因而调用本地即窗口类的OnFileChange()方法,从而实现在ListBox中添加信息。

    博文出处:@张逸,感谢!学习了!

  • 相关阅读:
    Java实现 LeetCode 27 移除元素
    Java实现 LeetCode 26 删除排序数组中的重复项
    Java实现 LeetCode 26 删除排序数组中的重复项
    Java实现 LeetCode 26 删除排序数组中的重复项
    Java实现 LeetCode 25 K个一组翻转链表
    Java实现 LeetCode 25 K个一组翻转链表
    Java实现 LeetCode 25 K个一组翻转链表
    Java实现 LeetCode 24 两两交换链表中的节点
    Java实现 LeetCode 24 两两交换链表中的节点
    Java实现 LeetCode 24 两两交换链表中的节点
  • 原文地址:https://www.cnblogs.com/xushaoxin/p/3202599.html
Copyright © 2011-2022 走看看