我眼中的事件委托
上一篇博文写了委托,总想知道委托的使用场景。网上查出事件委托、回调函数等。
今天我也写写对事件委托的认知,常思考并总结,对自己总是有好处的,能让知识更加系统完善。人无完人,虽然我也很怕引来大家的一堆谩骂声,但是我也想招来一群志同道合的友人。就像三国的曹操,有人谩骂,有人赞扬,有人示之为敌人,有人示之为我主。
好拉,不写点费话,总觉得缺少什么。下面谈谈事件委托,这是一对词组,拆分为事件(关键字event)、委托(关键字delegate)
网上看一位博友总结委托与事件的作用,而且对于事件委托的阐述也很棒。
委托的作用:
占位,在不知道将来要执行的方法的具体代码时,可以先用一个委托变量来代替方法调用(委托的返回值,参数列表要确定)。在实际调用之前,需要为委托赋值,否则为null。
事件的作用:
事件的作用与委托变量一样,只是功能上比委托变量有更多的限制。(比如:1.只能通过+=或-=来绑定方法(事件处理程序)2.只能在类内部调用(触发)事件。)
委托的声明使用,上一篇博文也讲了一部分内容,可以参照了解。
现在我们来看看ASP.NET中按钮的事件方法:
protected void btnClose_OnClick(object sender, EventArgs e)
=》方法:btnClose_OnClick(方法名如果按规定来命名的话,其实可以看出是一个按钮的Click点击事件)
=》参数:(1)sender:即触发事件的主体,事件的主体可以多样化,故被定义成object类型,通过它能区分不同事件的主体。多事件的回调函数就是通过它来区分
(2)e:即事件参数,当事件发生时,可以通过该参数来传递一些数据。如果你需要自定义它,可通过继承 EventArgs类来实现
完整的ASP.NET的例子如下,这个例子主要是说明了btnOpen注册了btnClose的事件,即点击btnOpen按钮会实现btnOpen+btnClose事件。
aspx页面代码:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="DelegeEventTest.WebForm1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="btnOpen" Text="自动化开关灯" runat="Server" OnClick="btnOpen_OnClick" />
<asp:Button ID="btnReset" Text="重置" runat="server" OnClick="btnReset_Onclick" />
<asp:Button ID="btnClose" Text="关灯" runat="Server" OnClick="btnClose_OnClick" />
<br /><br /><br />
<asp:Label ID="lblShow" runat="server" />
</div>
</form>
</body>
</html>
cs代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;namespace DelegeEventTest
{
public delegate void EventHandler1(object sender, EventArgs e);
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
this.btnOpen.Click += new EventHandler(btnClose_OnClick);
}protected void btnOpen_OnClick(object sender, EventArgs e)
{
this.lblShow.Text = "灯已经开启!";
this.lblShow.Text += "<br/>";
this.lblShow.Text += "过了一分钟后";
this.lblShow.Text += "<br/>";
}protected void btnClose_OnClick(object sender, EventArgs e)
{
this.lblShow.Text = "灯已经关闭!";
}
protected void btnReset_Onclick(object sender, EventArgs e)
{
this.lblShow.Text = string.Empty;
}
}
}
上面ASP.Net的例子大家好像连个delegate的关键字都没有看到,其实是因为微软已经封装好了,其位于命名空间System下面。
namespace System
{
// 摘要:
// 表示将处理不包含事件数据的事件的方法。
//
// 参数:
// sender:
// 事件源。
//
// e:
// 不包含任何事件数据的 System.EventArgs。
[Serializable]
[ComVisible(true)]
public delegate void EventHandler(object sender, EventArgs e);
}
然后我们看一下this.btnOpen.Click += new EventHandler(btnClose_OnClick);(鼠标点击this.btnOpen.Click里的click,然后按键盘F12)
// 摘要:
// 在单击 System.Web.UI.WebControls.Button 控件时发生。
[WebCategory("Action")]
[WebSysDescription("Button_OnClick")]
public event EventHandler Click;
说明按钮的点击事件需要注册一个事件委托,而btnClose_OnClick函数就是委托指向调用的方法。