ASP.NET中的事件处理
• 事件概述
• ASP.NET服务端事件
• ASP.NET服务端添加客户端事件
• 通过客户端事件引发服务端事件
• 事件使用的最佳实践
一、事件概述
• Visual Studio 项目很容易被看作一系列顺序执行的过程。事实上,多数程序都是事
件驱动的——即执行流程是由外界发生的事件所确定的。
• 事件是一个信号,它告知应用程序有重要情况发生。例如,用户单击窗体上的某个
控件时,窗体引发一个Click 事件并调用一个处理该事件的过程。
二、C#中使用事件需要的步骤
1.创建一个委托
2.将创建的委托与特定事件关联
3.编写事件处理程序
4.利用编写的事件处理程序生成一个委托实例
5.把这个委托实例添加到产生事件对象的事件列表中去,这个过程又叫订阅事件
三、ASP.NET中的事件
ASP.NET支持3个主要的事件组:
• 第一组包含在asp.net生成页面时自动发生,我们使用这些事件建立页面
• 第二组包含了用户与页面交互时发生的所有事件(这种最强大)。
• 第三种是html内部的事件,这些事件在浏览器上执行。
四、ASP.NET窗口事件处理
• 事件驱动(Event Driven)是窗口程序设计的核心,其重要性就相当于VC中的消息映射,不
了解事件驱动就无法深入窗口程序设计的殿堂。
• 在C#语言中,事件的处理主要有两种方法:
–委托式的事件处理模式(Delegation Event Model)
–对可重载方法(Event Method)的重载。
1.委托式的事件处理模式
委托式事件处理模式,就是将特定的事件委托给负责事件处理的方法来进行。
• 在.NET中,类有数据成员与函数成员、事件成员。事件成员就是那些与该类的对象相关的事件。
• 事件处理可通过委托关系来进行。委托关系可以这样来建立:
object.Event+=new EventHandle(Method); 其含义是:如果对象object发生了Event事件,就交由方法Method来处理。一个对象可以委托多个不同的处理,“+=”用来增加新的委托关系。
• Method是真正进行事件处理的地方,格式为:
public void Method(object sender,EventArgse);
EventArgs是.NET Framework中有关事件的基础类,所有发生的事件都被包装成EventArgs类或其子类的对象。当事件发生时,Method会收到这两个参数。一旦建立了委托关系,系统自动在特定事件发生时,转而执行您所委托的事件处理方法。
在Asp.net中设计时添加事件和运行时添加事件两种方法!
2.重载事件方法
• 在C#中,针对不同类所相关的事件,除了定义有事件成员外,也定义了可重载的事件方法,可通过重载这些事件方法来设计你所希望的对应事件处理。
• 这些可重载的事件方法名称皆以“On”开头,且被声明为“virtual”,一个被声明成virtual的方法,就代表它可被重载,被声明成override的方法也代表它可被重载,如果声明成abstract则必须被重载。例如按钮的Click事件,就有一个对应的可重载的OnClick事件方法。
protected override void OnClick(EventArgs e)
{
this.Page.Response.Write("重载");
}
五、ASP.NET服务端添加客户端事件
• 尽管从技术角度讲,Microsoft® ASP.NET服务器控件的所有功能都可以在服务器端执行,但通常情况下通过添加客户端脚本可以大大增强服务器控件的可用性。例如,ASP.NET 验证Web 控件可以在服务器端执行所有的验证检查。但是,对于高版本浏览器,验证Web 控件也会发送客户端脚本,以在客户端进行验证。
1.ASP.NET服务端添加客户端事件
ASP.NET 服务器控件可以发送两种客户端脚本:
• 客户端脚本块:客户端脚本块通常是用JavaScript 编写的,其中通常包含在发生特定的客户端事件时执行的函数。
• 客户端HTML 属性:客户端HTML 属性提供将客户端事件与客户端脚本联系在一起的方法。
2.ASP.NET中发送客户端脚本块
使用System.Web.UI.Page 类包含的两个方法可以将客户端脚本代码发送到由ASP.NET Web 页面提供的HTML 中:
• RegisterStartupScript(key, script) :在Web 窗体的结尾处(在</form> 标识之前)发送脚本块。
• RegisterClientScriptBlock(key, script):在Web 窗体的开始处(紧接着<form runat=“server”> 标识之后)发送脚本块。
3.ASP.NET 中发送HTML 属性
• 这种方法通常只适用于从System.Web.UI.WebControls.WebControl 类导出的服务器控件,因为从这个类导出的控件会发送某些HTML 元素。
• WebControl 类包含一个将HTML 元素属性添加到由Web 控件发出的HTML 元素的方法。该方法称为AddAttributesToRender(),它只有一个输入参数,即HtmlTextWriter 的实例。
protected void Page_Load(object sender, System.EventArgs e)
{
string script = @"return confirm('真的要删除吗?');";
this.Button1.Attributes.Add("onclick",script);
if (!Page.IsStartupScriptRegistered("PopUp")&&!Page.IsPostBack)
{
string scriptBlock =
@"<script language=""JavaScript"">alert(""发送客户端脚本"");
</script>";
Page.RegisterStartupScript("PopUp", scriptBlock);
}
}
protected void Button1_Click(object sender, EventArgs e)
{
Response.Write("Button1_Click on server");
}
Note:
1. 做完客户端,无返回值或返回值是true再接着做服务端,如果返回值是false的话,就不做服务端。
2. 客户端可以添加的事件可以在MSDN的对应Html控件中找到。
六、通过客户端事件引发服务端事件
1.页面
<SCRIPT language="javascript">
function ConfirmUpdate(cmd)
{
if(confirm("真的要保存吗?"))
{
eval(cmd);// eval函数先解释Javascript代码,然后在执行它
}
else
{
alert("已经取消!");
}
}
</SCRIPT>
2.代码
protected void Page_Load(object sender, System.EventArgs e)
{
string strCMD = Page.GetPostBackClientHyperlink(btnSave, "");
string script = @"Javascript:ConfirmUpdate(""EVAL_MESSAGE"");";
script = script.Replace( "EVAL_MESSAGE" , strCMD );
ddlTest.Attributes.Add("onchange",script);
}
七、示例
1.服务器控件的刷新问题(还是返回页面刷新前的位置)
本质上还是利用客户端脚本解决问题,客户端的脚本
<script language="javascript">
function ViewObj(objName)
{var obj = document.all.item(objName);
if (obj != null)
{
obj.scrollIntoView();
obj.focus();
}
}
function ToDo(){
setTimeout("ViewObj('Button1')",1000);
}
window.onload = ToDo;
</script>
在服务器端
protected void Page_Load(object sender, System.EventArgs e)
{
if(!Page.IsClientScriptBlockRegistered("MyScript")) this.RegisterClientScriptBlock("MyScript",ScriptHelper.GetViewControlScript("Button1"));}
ScriptHelper类的代码:这里最好是使用stringBuilder类来构造,效率会提高很多
public class ScriptHelper
{
/// <summary>
/// 获取客户端查看控件的脚本
/// </summary>
/// <param name="controlName"></param>
/// <returns>脚本代码</returns>
public static string GetViewControlScript(string controlName)
{
//创建客户端函数ViewObj
string script = "/n";
script += "<script language=/"javascript/">/n";
script += "function ViewObj(objName)/n";
script += "{/n";
script += "var obj = document.all.item(objName);/n";
script += "if (obj != null)/n";
script += "{/n";
script += "/tobj.scrollIntoView();/n";
script += "/tobj.focus();/n";
script += "}/n";
script += "}/n";
//创建客户端函数ToDo
script += "function ToDo()";
script += "{/n";
script += string.Format("setTimeout(/"ViewObj('{0}')/",1000);/n", controlName);
script += "}/n";
script += "window.onload = ToDo;/n";
script += "</script>/n";
return script;
}
}
2.回车到达指定按钮并触发事件
<SCRIPT LANGUAGE="javascript">
function SubmitKeyClick(button)
{
if (event.keyCode == 13) //回车键盘
{
event.returnValue = false;
document.all[button].click();
}
}
</SCRIPT>
protected void Page_Load(object sender, System.EventArgs e)
{
tbInput.Attributes.Add("onkeydown","SubmitKeyClick('btnOK');");
}