《2022年ASP.NET服务器控件封装--.[归 .pdf》由会员分享,可在线阅读,更多相关《2022年ASP.NET服务器控件封装--.[归 .pdf(16页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、最近,正在学习ASP.NET服务器控件封装相关的知识,把自己学到的和大家分享下。本次内容的概要如下:1. 事件以及为什么需要事件驱动机制;2. 回发的原理;3. 异步回调的原理;4. 事件回发的实现;5. 异步回调的实现。了解了本次内容的概要,接下来就分节次说明了。1. 事件以及为什么需要事件驱动机制在 C# 语言详解一书中对事件的定义是“ 事件是一种使对象或类能够提供通知的成员” ,在这里换句话说就是页面中已注册事件的对象能够对用户的操作进行捕获并处理。那么为什么需要引用事件机制呢?大家都知道,如果在类A 的实例对象中创建了一个类B 的实例对象,那么在类A 的实例对象中就可以通过该类B 的实
2、例对象调用类B 公开的任何方法和属性等。就像用户Page 对象中包含了创建了一个TextBox对象, Page 对象就可以通过TextBox对象去调用Text属性。但是如果需要在上述的TextBox对象中调用Page 对象中的某些属性或方法又该怎样处理呢?显然包含调用就行不通了,事件机制正好解决该问题。现就 TextBox的 TextChanged事件来描述下。首先需要在TextBox中声明 TextChanged委托,并通过页面注册将该委托和页面类处理事件函数关联起来(上述代码就是将TextBox1的 TextChanged事件注册到页面类中)。然后在 TextBox类体内调用TextCha
3、nged委托关联的事件函数就可以了。这样,当页面类对象中 TextBox控件的 Text发生改变时TextBox首先执行完自己内部逻辑处理后,就会调用页面类中OnTextChanged事件函数 TextBox1_TextChanged(),而 TextBox1_TextChanged()函数是页面类中的一个方法,所以 TextBox就可以在该函数内调用页面类中的其他方法和属性了。(当然也是可以调用TextBox1自己的)。2. 回发的原理名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第
4、 1 页,共 16 页 - - - - - - - - - Web 开发的人员都知道,客户端回发到服务端的事件只有一个,那么在服务端怎样的区分用户执行了怎样的操作呢?这里首先从ASP.NET的页面请求说起了。在 ASP.NET中处理页面时, 前后两个页面之间是无状态连接的,也就是说客户端的前后两次请求是相互独立的,服务端不会保存前一次请求的页面状态。如此就引入了视图状态机制(我会在以后的文章中和大家分享下ASP.NET开发的视图状态和控件状态机制的研究乐趣)来处理前后两次请求的逻辑处理,其原理就是在前一次请求发生后服务端将页面的逻辑信息保存在一个隐藏的字段中回送到客户端,当后一次请求发生时服务
5、端首先取出该隐藏字段中的值并恢复到各个视图控件中,等逻辑处理完后再将新的数据保存到该隐藏字段会送到客户端,从而延续了两次页面之间的状态信息。本文中要说明的回发就是在视图状态机制基础上完成的,也就是通过比较发送到服务端的控件当前值和保存在隐藏字段中的旧值,从而决定是否触发哪些事件。当然, 自定义的控件类必须通过继承IPostBackDataHander接口来完成事件的回发功能。3. 异步回调的原理和回发不同, 回调就是从客户端到服务端,在服务端处理相关逻辑完了将处理的数据返回给客户端,就相当于客户端调用了服务端的方法(这和Web Service很像)一样,将处理的数据作为返回的结果供客户端程序处
6、理。异步回调过程中,ASP.NET会修改页面正常的生命周期来处理请求,而回发则是ASP.NET 会用一个完整的页面生命周期处理请求。另外,异步回调过程中,用户还可以进行其他的操作,客户端页面并不会重新刷新。4. 事件回发的实现上面说过, 客户端到服务端的事件只有一个 回发事件。 那么, 服务端怎样使自己的控件捕获该回发事件呢?你需要将你的控件类继承IPostBackEvnetHander接口并实现该接口中唯一的一个方法:RaisePostBackEvent(string eventArgument)。下面就以一个简单的实例说明下:(1).首先创建一个服务器控件项目和测试项目。(这里介绍了项目的
7、创建方法,以后就不再说明了哦!)打开 VS2008新建项目,在弹出的对话框中选中ASP.NET服务器控件模板,输入你项目名并选择路径,如下图1。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 16 页 - - - - - - - - - 图 1 然后在资源管理器中的“ 解决方案 . ”上右键 “ 添加 ”=“ 新建项目 ” (如图 2 所示),弹出如图 1 对话框,选中“ASP.NET Web 应用程序 ” 后输入项目名(这里仅只为了测试控件的一些处理,所以命名为test
8、 )确定。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 16 页 - - - - - - - - - 图 2 (2).继承 IPostBackEvnetHander接口并实现接口方法。如下图所示, ServerControl1继承了 IPostBackEvnetHander接口,将鼠标悬停在该接口上片刻会弹出实现接口方法提示对话框,如下图3 所示。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整
9、理 - - - - - - - 第 4 页,共 16 页 - - - - - - - - - 选择 “ 实现接口 . ”就可自动生成该接口需要实现的方法的空函数代码。#region IPostBackEventHandler 成员publicvoid RaisePostBackEvent(string eventArgument) thrownew NotImplementedException(); #endregion(3).接下来,就开始实现该方法了。protectedoverridevoid RenderContents(HtmlTextWriter output) /output.W
10、rite(Text); output.Write(, 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 16 页 - - - - - - - - - this.UniqueID); #region IPostBackEventHandler 成员publicvoid RaisePostBackEvent(string eventArgument) /throw new NotImplementedException(); OnCliclk(EventArgs.Empty);
11、 #endregion/* Click事件委托 */publicevent EventHandler Click; protectedvirtualvoid OnCliclk(EventArgs e) if (Click != null) Click(this, e); 上述代码中首先定义了一个Click 委托和 Onclick事件函数,用于与页面注册的单击事件函数关联。而在RaisePostBackEvent()方法中只调用了OnCliclk(EventArgs.Empty);方法,处理用户的逻辑。(4).在控件的RaisePostBackEvent()方法处打下断点,并从工具栏中将上述控件
12、(ServerControl1)拖放到 test项目中的 Default.asp页面中,运行测试下。单击按钮后,代码的执行并没有进入断点处函数。为什么?因为 IPostBackEvnetHander接口只提供捕获回发事件,但并没有回发就谈不上捕获了(客户端 button类型的 input按钮不会触发回发事件的)。将 input类型该为submit类型再试下,这次可以了吧。(5).控件自动回发实现上面只用当按钮类型改为submit类型时才能捕获回发事件,但总不能任何的控件都需要带上一个提交按钮吧,别急,下面就说说控件的客户端自动回发。名师资料总结 - - -精品资料欢迎下载 - - - - -
13、- - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 6 页,共 16 页 - - - - - - - - - 要实现控件客户端的自动回发,可以采用两种方式 通过 GetPostBackEventReference 或 GetPostBackClientHyperlink方法获取客户端回发函数的引用。修正上面的代码如下:protectedoverridevoid RenderContents(HtmlTextWriter output) /output.Write(Text); /output.Write(, / this.UniqueID); ou
14、tput.Write(, this.UniqueID, Page.ClientScript.GetPostBackEventReference(this, ); 或者protectedoverridevoid RenderContents(HtmlTextWriter output) /output.Write(Text); /output.Write(, this.UniqueID); output.Write(, this.UniqueID, Page.ClientScript.GetPostBackClientHyperlink(this, ); 运行程序,测试下,你的控件现在就可以自动
15、回发了。(6).双击 Default.asp页面中的【点击我】按钮,Default.asp.cs文件中为自动生成该按钮的单击事件函数。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 7 页,共 16 页 - - - - - - - - - protectedvoid ServerControl1_Click(object sender, EventArgs e) 打上断点,单步跟下,在该函数中可以调用页面类中的方法和属性了。这就是Button对象通过事件调用Page 对象中的方法和属
16、性了。5. 异步回调的实现异步回调的处理就不是控件封装中的内容了,单为了让大家能够分清回发和回调的区别,还是讲解下。异步回调是在页面类中处理的,同样,页面类需要继承ICallBackEventHandle接口并实现接口方法来增加该页面类的异步回调的功能。这里,就需要从JavaScript开始着手了,还是沿用上面的工程进行实例讲解。(1).在上面的Default.asp页面中添加一个按钮和用于显示结果的Span 元素。无标题页 显示异步回调两个参数结果: Args1. Args2. 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - -
17、名师精心整理 - - - - - - - 第 8 页,共 16 页 - - - - - - - - - (2).Default.asp页面后台文件类继承ICallBackEventHandle接口并实现接口方法。public partial class _Default : System.Web.UI.Page, ICallbackEventHandler protected void Page_Load(object sender, EventArgs e) protected void ServerControl1_Click(object sender, EventArgs e) #re
18、gion ICallbackEventHandler 成员 public string GetCallbackResult() throw new NotImplementedException(); public void RaiseCallbackEvent(string eventArgument) throw new NotImplementedException(); #endregion (3).在页面类的Page_Load事件函数中加入下面代码:protectedvoid Page_Load(object sender, EventArgs e) string cbRe = Pa
19、ge.ClientScript.GetCallbackEventReference( this, arg, CallBackServe, context); string callbackscript; callbackscript = function CallPageServe(arg,context)+ + cbRe + ; Page.ClientScript.RegisterClientScriptBlock(this.GetTy名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第
20、 9 页,共 16 页 - - - - - - - - - pe(), CallPageServe, callbackscript, true); 其中首先通过page对象引用 ClientScript.GetCallbackEventReference()方法获取该页面的回调函数的应用,然后将该应用通过RegisterClientScriptBlock()方法注册到客户端页面中。这里需要说明下,其中GetCallbackEventReference方法的第一个参数是控件对象的引用,通常情况下是this ;第二个和第四个参数(“arg”和“context ” )是处理客户端想服务端回调的函数C
21、allPageServe函数的传入参数;真正重要的就是第三个参数“CallBackServe ” ,这是回调过程中服务端处理完后返回到客户端后处理返回数据的JS 函数名。(4).返回到 Default.asp页面,双击 “ButtonCallBack ”按钮,为该按钮注册客户端JS单击事件函数ButtonCallBack_onclick()。 function ButtonCallBack_onclick() CallPageServe(args1, args2); function CallBackServe(returnValue, context) document.getElement
22、ById(ResultShowArg1).innerHTML = returnValue; document.getElementById(ResultShowArg2).innerHTML = context; 其中 ButtonCallBack_onclick()中调用的CallPageSever()就是回调的触发函数。而 CallBackServe()就是客户端处理回调返回数据的JS 函数。(5).回到 Default.asp.cs文件,为该页面类添加一个String 字符串对象,并在ICallBackEventHandle接口方法的函数体内做相应的处。string returnValu
23、e = ; #region ICallbackEventHandler 成员publicstring GetCallbackResult() /throw new NotImplementedException(); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 10 页,共 16 页 - - - - - - - - - return returnValue; publicvoid RaiseCallbackEvent(string eventArgument) /throw ne
24、w NotImplementedException(); returnValue = eventArgument; #endregion(6).运行检验下,单击ButtonCallBack按钮后显示回调的结果。在你感兴趣的地方打上断点单步跟下吧,你会发现还有其他有趣的东东。还是附上全部源码吧。Default.asp.cs文件using System; using System.Collections; using System.Configuration; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - -
25、 - - - - 第 11 页,共 16 页 - - - - - - - - - using System.Data; using System.Linq; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Xml.Linq; namespace test publicpa
26、rtialclass _Default : System.Web.UI.Page, ICallbackEventHandler protectedvoid Page_Load(object sender, EventArgs e) string cbRe = Page.ClientScript.GetCallbackEventReference(this, arg, CallBackServe, context); string callbackscript; callbackscript = function CallPageServe(arg,context) + + cbRe + ; P
27、age.ClientScript.RegisterClientScriptBlock(this.GetType(), CallPageServe, callbackscript, true); protectedvoid ServerControl1_Click(object sender, EventArgs e) string returnValue = ; #region ICallbackEventHandler 成员名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 12 页,
28、共 16 页 - - - - - - - - - publicstring GetCallbackResult() /throw new NotImplementedException(); return returnValue; publicvoid RaiseCallbackEvent(string eventArgument) /throw new NotImplementedException(); returnValue = eventArgument; #endregion Default.asp 无标题页 名师资料总结 - - -精品资料欢迎下载 - - - - - - - -
29、- - - - - - - - - - 名师精心整理 - - - - - - - 第 13 页,共 16 页 - - - - - - - - - 显示异步回调两个参数结果: Args1. Args2. function ButtonCallBack_onclick() CallPageServe(args1, args2); function CallBackServe(returnValue, context) document.getElementById(ResultShowArg1).innerHTML = returnValue; document.getElementById(Re
30、sultShowArg2).innerHTML = context; ServerControls1 using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Web; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 14 页,共 16 页 - - - - - - - - - using
31、System.Web.UI; using System.Web.UI.WebControls; namespace PostBackEventControlDome DefaultProperty(Text) DefaultEvent(Click) ToolboxData() publicclass ServerControl1 : WebControl, IPostBackEventHandler Bindable(true) Category(Appearance) DefaultValue( ) Localizable(true) publicstring Text get String
32、 s = (String)ViewStateText; return (s = null) ? + this.ID + : s); set ViewStateText = value; protectedoverridevoid RenderContents(HtmlTextWriter output) /output.Write(Text); /output.Write(, /this.UniqueID); /output.Write(, /this.UniqueID, Page.ClientScript.GetPostBackClientHyperlink(this, ); output.
33、Write(, this.UniqueID, Page.ClientScript.GetPostBackEventReference(this, ); #region IPostBackEventHandler 成员publicvoid RaisePostBackEvent(string eventArgument) /throw new NotImplementedException(); OnCliclk(EventArgs.Empty); #endregion/* Click事件委托 */publicevent EventHandler Click; protectedvirtualvoid OnCliclk(EventArgs e) if (Click != null) Click(this, e); 最后:名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 16 页,共 16 页 - - - - - - - - -