你的位置:首页 > ASP.net教程

[ASP.net教程]浅谈Winform事件的实现以及模拟其事件的实现


当我们初学Winform的时候被其神奇的事件功能所吸引,当点击一个按钮时,便会跳到我们所写的点击方法当中去。然而这并不符合我们对方法的理解,究竟.net在后面帮助我们实现了什么。我们怎样模拟其事件的实现呢。下面先从Button的Click方法说起。

1.首先查看设计器自动生成的代码

 

 partial class Form1  {       #region Windows 窗体设计器生成的代码    /// <summary>    /// 设计器支持所需的方法 - 不要    /// 使用代码编辑器修改此方法的内容。    /// </summary>    private void InitializeComponent()    {      //实例化一个按钮      this.button1 = new System.Windows.Forms.Button();      this.SuspendLayout();      //       // button1      //       this.button1.Location = new System.Drawing.Point(491, 100);      this.button1.Name = "button1";      this.button1.Size = new System.Drawing.Size(75, 23);      this.button1.TabIndex = 0;      this.button1.Text = "button1";      this.button1.UseVisualStyleBackColor = true;      //添加点击事件      this.button1.Click += new System.EventHandler(this.button1_Click);          }    #endregion    private System.Windows.Forms.Button button1;}

 

 我们发现了对事件的添加 this.button1.Click += new System.EventHandler(this.button1_Click);

this.button1.Click中的Click是什么呢?我们F12转到定义看一下(注意:Button继承自Control(所有控件父类))

我们发现event,Click是一个事件,然后我们反编译看一下(可以看到+=,-=的实现)

EventHandler转到定义sender事件源(就是被谁引发的),e(事件数据)

我们从上而下进行逆向分析
01.System.Windows.Forms.dll!System.Windows.Forms.Control.OnClick(System.EventArgs e) + 0x62 字节,我们对
System.Windows.Forms.Control.OnClick反编译一下,handler不为空说明事件被订阅,执行
 private void button1_Click(object sender, EventArgs e){}

03System.Windows.Forms.dll!System.Windows.Forms.Button.OnMouseUp(System.Windows.Forms.MouseEventArgs
mevent = {X = 36 Y = 13 Button = Left}) + 0xac 字节,我们对System.Windows.Forms.Button.OnMouseUp反编译一下,
该方法最后调用Control.OnMouseUp方法执行鼠标弹起的事件

04System.Windows.Forms.dll!System.Windows.Forms.Control.WmMouseUp(ref System.Windows.Forms.Message m, System.Windows.Forms.MouseButtons button, int clicks) + 0x274 字节我们对System.Windows.Forms.Control.WmMouseUp反编译一下,这是对鼠标事件的判定,我们会惊奇的发现里面有对单击与双击的判定。

好了到目前为止我们已经对Winform事件有了一定的了解,那我们如何借助这个思想来实现我们自己的事件处理呢?

接下来我们模拟一个场景,我们有一个文本文件,我们监听文件,如果文本文件发生改变(相当于上面所说的鼠标监听触发事件),触发事件向管理员和用户发一条信息提示(这里的人相当于button对象,向不同人发模拟Winform不同控件的click事件)。利用刚才的Winform事件技术实现一下;

1首先定义一个事件的委托

 

 //处理文件发生变化后的委托声明  public delegate void MonitorEventHandler(object sender, EventArgs e);

 

2事件传递的事件数据

//事件数据类    继承自EventArgs  public class MsgEventArgs : EventArgs  {    /// <summary>    ///     /// </summary>    /// <param name="changeTime">修改时间</param>    /// <param name="toSend">提示信息</param>    public MsgEventArgs(DateTime changeTime, string toSend)    {      this.ChangeTime = changeTime;      this.ToSend = toSend;    }    // 修改时间    public DateTime ChangeTime { get; set; }    // 提示信息    public string ToSend { get; set; }  }

3 MonitorText类监控文件类(相当于上面讲的鼠标监听类)

 public class MonitorText  {    //定义监控文本事件    public event MonitorEventHandler MonitorEvent;    //上次文件更新时间用于判断文件是否修改过    private DateTime _lastWriteTime = File.GetLastWriteTime(@"C:\Users\HHY\Desktop\1.txt");    public MonitorText()    {    }    // 文件更新调用    protected virtual void OnTextChange(MsgEventArgs e)    {      if (MonitorEvent != null)      {        //不为空,处理事件        MonitorEvent(this, e);      }    }    //事件监听的方法    public void BeginMonitor()    {      DateTime bCurrentTime;      while (true)      {        bCurrentTime = File.GetLastWriteTime(@"C:\Users\HHY\Desktop\1.txt");        if (bCurrentTime != _lastWriteTime)        {          _lastWriteTime = bCurrentTime;          MsgEventArgs msg = new MsgEventArgs(bCurrentTime,"文本改变了");          OnTextChange(msg);        }
//0.1秒监控一次 Thread.Sleep(100); } } }

4管理员类(相对于Button类)

public class Administrator  {   //管理员事件处理方法    public void OnTextChange(object Sender, EventArgs e)    {      Console.WriteLine("尊敬的管理员:"+DateTime.Now.ToString() + ": 文件发生改变.");    }  }

5用户类(相对于Button类以外的控件类)

public class User  {    //用户事件处理方法    public void OnTextChange(object Sender, EventArgs e)    {      Console.WriteLine("尊敬的用户:" + DateTime.Now.ToString() + ": 文件发生改变.");    }  }

6程序的Main方法

 class Program  {    //定义监控文本对象    static MonitorText MonitorTextEventSource;    static void Main(string[] args)    {          MonitorTextEventSource = new MonitorText();      //1. 启动后台线程添加监视事件      var thrd = new Thread(MonitorTextEventSource.BeginMonitor);      thrd.IsBackground = true;      thrd.Start();      //2实例化管理员类      Administrator ad = new Administrator();      //3实例化用户类      User user = new User();      //4订阅事件      MonitorTextEventSource.MonitorEvent += ad.OnTextChange;      MonitorTextEventSource.MonitorEvent += user.OnTextChange;      Console.ReadLine();    }  }

运行程序

好了到现在,我们的模拟完成了,大体将Winform事件的流程实现了一遍,由于自己本身也也是一个小白理解的不到位的地方请大家指出来,我把程序源码放在了下面,大家可以调试运行一下。

源码地址:http://pan.baidu.com/s/1bRelEQ