转:http://www.cnblogs.com/xieex/archive/2008/07/10/1240334.html
一、ASP.NET中的事件主要支持3个主要的事件组:
1、包含在asp.net生成页面时自动生成,我们使用这些事件建立页面(如page_load等)
2、包含了用户与页面交互时发生的所有事件(这种最强大)
3、html内部的事件,这些事件在浏览器上执行(主要是由javascript来实现)。
在C#语言中,事件的处理主要有两种方法:
1、委托式事件处理模式(Delegation Event Model) (VS2003中需要手工建立事件的委托关系,VS2005不需要了。)
2、对可重载方法(Event Method)的重载 (在控件代码中重载方法)
二、ASP.NET服务端添加客户端事件:
服务器控件并不是所有的操作都是在服务器端执行的,有的事件是通过客户端脚本来执行的,这样可以大大增强服务器控件的可用性。如ASP.NET验证控件,可以把部分工作放在客户端进行验证。
ASP.NET服务器控件可以发送两种客户端脚本:
1、客户端脚本块:客户端脚本块通常是用JavaScript编写的,其中通常包含在发生特定的客户端事件时执行的函数。
发送脚本块的方法是使用System.Web.UI.Page类包含的两个方法可以将客户端代码发送到由ASP.NET Web页面提供的HTML中:
(1)、RegisterStartupScript(key,script):在Web窗体的结尾处(在</form> 标记之前)发送脚本块。
(2)、RegisterClientScriptBlock(key,script):在Web窗体的开始处(紧接着<form runat="server">标识之后)发送脚本块。
如:
1
protected
override
void
OnPreRender(EventArgs e)
2
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
{
3
if (!Page.ClientScript.IsClientScriptBlockRegistered("Common"))
4![](https://i-blog.csdnimg.cn/blog_migrate/3112b7b6526db5bc83e275260ae60525.gif)
{
5
Page.ClientScript.RegisterClientScriptBlock(typeof(Page), "Common", ClientJavaScriptCodeScipt("Common.js"));
6
}
7
if (!Page.ClientScript.IsClientScriptBlockRegistered(ScriptKey))
8![](https://i-blog.csdnimg.cn/blog_migrate/3112b7b6526db5bc83e275260ae60525.gif)
{
9
Page.ClientScript.RegisterClientScriptBlock(typeof(Page), ScriptKey, ClientJavaScriptCodeScipt("DateTime.js"));
10
}
11
}
2、客户端HTML属性:客户端HTML属性提供将客户端事件与客户端脚本联系在一起的方法。
这种方法只适用于从System.Web.UI.WebControls.WebControl类导出的服务器控件,因为从这个类导出的控件会发送某些HTML元素。
WebControl类包含一个将HTML元素属性添加到由Web控件发出的HTML元素的方法,该方法称为AddAttributesToRender(),它只有一个输入参数,即HtmlTextWriter的实例。
当然在现在开发控件中,也没必要通过这种方式来为HTML元素添加事件,特别在采用AJAX模式的情况下,完全可以在客户端通过$addHandler来为HTML元素绑定事件。
1
/**/
/// <summary>
2
/// 将此控件呈现给指定的输出参数。
3
/// </summary>
4
/// <param name="output"> 要写出到的HTML 编写器</param>
5
protected
override
void
AddAttributesToRender(HtmlTextWriter output)
6
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
{
7
output.AddAttribute("onmousedown","setday(this);");
8
output.AddAttribute("onkeypress", "EnsureNumeric(event)");
9![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
10
base.AddAttributesToRender(output);
11
}
下面的例子说明了ASP.NET服务端如何添加客户端事件:
1
using
System;
2
using
System.Data;
3
using
System.Configuration;
4
using
System.Collections;
5
using
System.Web;
6
using
System.Web.Security;
7
using
System.Web.UI;
8
using
System.Web.UI.WebControls;
9
using
System.Web.UI.WebControls.WebParts;
10
using
System.Web.UI.HtmlControls;
11
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
12
namespace
ServerToClientScript
13
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
{
14
public partial class _Default : System.Web.UI.Page
15![](https://i-blog.csdnimg.cn/blog_migrate/3112b7b6526db5bc83e275260ae60525.gif)
{
16
protected void Page_Load(object sender, EventArgs e)
17![](https://i-blog.csdnimg.cn/blog_migrate/3112b7b6526db5bc83e275260ae60525.gif)
{
18
string script = "return confirm('真的要删除吗?');";
19
this.Button1.Attributes.Add("onclick",script);
20![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
21
if ((!Page.IsStartupScriptRegistered("PopUp")&&(!Page.IsPostBack)))
22![](https://i-blog.csdnimg.cn/blog_migrate/3112b7b6526db5bc83e275260ae60525.gif)
{
23
string scriptBlock = "<script language='JavaScript'>alert('发送客户端脚本!');</script>";
24
Page.RegisterStartupScript("PopUp",scriptBlock);
25
}
26
}
27
}
28
}
三、通过客户端事件引发服务端事件:
其实服务端控件的服务端事件是通过客户端的JavaScript模拟出来的,如我在页面上添加了一个服务器控件DropDownList,并设置其AutoPostBack为True,然后设置它的 SelectedIndexChanged事件
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
}
运行页面后发现HTML代码为:可以看出服务端SelectedIndexChanged事件模拟成JavaScript中的onchange事件。
1
<!
DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
>
2
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
3
<
html
xmlns
="http://www.w3.org/1999/xhtml"
>
4
<
head
><
title
>
5
无标题页
6
</
title
></
head
>
7
<
body
>
8
<
form
name
="form1"
method
="post"
action
="MNEvent.aspx"
id
="form1"
>
9
<
div
>
10
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
11
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
12
<input type="hidden" name="__LASTFOCUS" id="__LASTFOCUS" value="" />
13
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwULLTE3ODI0MjgzNjcPZBYCAgMPZBYCAgEPEGRkFgFmZGSYTeyI45LmYps34yPH/GyUwiYstw==" />
14
</
div
>
15
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
16
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
<
script
type
="text/javascript"
>
17
<!--
18
var theForm = document.forms['form1'];
19![](https://i-blog.csdnimg.cn/blog_migrate/3112b7b6526db5bc83e275260ae60525.gif)
if (!theForm)
{
20
theForm = document.form1;
21
}
22![](https://i-blog.csdnimg.cn/blog_migrate/3112b7b6526db5bc83e275260ae60525.gif)
function __doPostBack(eventTarget, eventArgument)
{
23![](https://i-blog.csdnimg.cn/blog_migrate/3112b7b6526db5bc83e275260ae60525.gif)
if (!theForm.onsubmit || (theForm.onsubmit() != false))
{
24
theForm.__EVENTTARGET.value = eventTarget;
25
theForm.__EVENTARGUMENT.value = eventArgument;
26
theForm.submit();
27
}
28
}
29
// -->
30
</
script
>
31
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
32
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
33
<
div
>
34
<
select
name
="DropDownList1"
οnchange="javascript:setTimeout('__doPostBack(\'DropDownList1\',\'\')', 0)"
id
="DropDownList1"
>
35
<
option
selected
="selected"
value
="男"
>
男
</
option
>
36
<
option
value
="女"
>
女
</
option
>
37
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
38
</
select
></
div
>
39
40
<
div
>
41
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
42
<
input
type
="hidden"
name
="__EVENTVALIDATION"
id
="__EVENTVALIDATION"
value
="/wEWBALgifCwDwKd5I/lCgKU4aSLBgLQuaSLBtn23paAhgqUhPSsi0GZsi57eadh"
/>
43
</
div
></
form
>
44
</
body
>
45
</
html
>
46
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
47
</
html
>
既然服务器端控件的事件是通过客户端的JavaScript模拟出来,那么我们就可以通过客户端事件来引发服务器事件。
在控件开发中,控件的服务端事件就是通过客户端的JavaScript模拟出来的(__doPostBack)
如例子ClientToServerEvent(附件中有代码)
通过DropDownList的onchange客户端事件来引发服务端控件Button的服务端事件Click事件,如:
1
using
System;
2
using
System.Data;
3
using
System.Configuration;
4
using
System.Collections;
5
using
System.Web;
6
using
System.Web.Security;
7
using
System.Web.UI;
8
using
System.Web.UI.WebControls;
9
using
System.Web.UI.WebControls.WebParts;
10
using
System.Web.UI.HtmlControls;
11
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
12
namespace
ServerToClientScript
13
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
{
14
public partial class ClientToServerEvent : System.Web.UI.Page
15![](https://i-blog.csdnimg.cn/blog_migrate/3112b7b6526db5bc83e275260ae60525.gif)
{
16
protected void Page_Load(object sender, EventArgs e)
17![](https://i-blog.csdnimg.cn/blog_migrate/3112b7b6526db5bc83e275260ae60525.gif)
{
18
string strCMD = Page.GetPostBackClientHyperlink(Button1,"");
19
string script = @"Javacript:ConfirmUpdate(""EVAL_MESSAGE"");";
20
script = script.Replace("EVAL_MESSAGE", strCMD);
21
DropDownList1.Attributes.Add("onchange",script);
22
}
23![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
24
protected void Button1_Click(object sender, EventArgs e)
25![](https://i-blog.csdnimg.cn/blog_migrate/3112b7b6526db5bc83e275260ae60525.gif)
{
26
Response.Write("我从服务器来,已经保存!");
27
}
28
}
29
}
30
在页面上写JavaScript脚本:
1
<
script type
=
"
text/javascript
"
>
2
function
ConfirmUpdate(cmd)
3
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
{
4
if(confirm("真的要保存吗?"))
5![](https://i-blog.csdnimg.cn/blog_migrate/3112b7b6526db5bc83e275260ae60525.gif)
{
6
eval(cmd); //eval函数调用一个字符串中包含的命令
7
}
8
else
9![](https://i-blog.csdnimg.cn/blog_migrate/3112b7b6526db5bc83e275260ae60525.gif)
{
10
alert("我来自客户端,已经取消!");
11
}
12
}
13
<
/
script>
这样当我的DropDownList选项改变时,触发onchange客户端事件,然后由该事件引发Button服务端事件。
四、ASP.NET事件模型机制
1、ASP.NET之所以对于以前的ASP是一个革命性的巨变,在很大程度上是由于ASP.NET技术是一种基于事件驱动的全新技术。
2、在ASP.NET中时间的触发和处理是在客户端和服务端进行的。
3、ASP.NET中,如果频繁和服务器进行事件信息传递,会大大降低服务器的处理效率和性能,因而有些事件如OnMouseOver没有提供;
4、但提供了Change事件,为了提高效率它们被缓存在客户端,等到再一次事件信息被发送到服务器端时一同发送回去。
如文本框的change事件,下拉框的change事件,
如两个控件的change事件中:
1
protected
void
DropDownList1_SelectedIndexChanged(
object
sender, EventArgs e)
2
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
{
3
Response.Write("DropDownList控件选择改变!<br>");
4
}
5
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
6
protected
void
TextBox1_TextChanged(
object
sender, EventArgs e)
7
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
{
8
Response.Write("TextBox文本改变!<br>");
9
}
如果控件本身的AutoPostBack设置为false(默认是false)时,文本框和下拉框发生
改变时,不会执行change事件的,而是将事件信息缓存在客户端,
当在页面上点击一个服务器端控件Button,
protected void Button1_Click(object sender, System.EventArgs e)
{
Response.Write("点击了Button按钮!<br>");
}
此时将客户端中的事件信息发送到服务器端,执行所有的事件,返回到客户端的信息为:
TextBox文本改变!
DropDownList控件选择改变!
点击了Button按钮!
具体例子代码见附件。
ServerToClientScript.rar