以上是处理回传数据的实现要点,掌握这些要点对于事件处理具有至关重要的意义。同时,其内容也说明了以下.NET框架处理回传数据的过程: (1)首先在发送的内容中搜索与实现IPostBackDataHandler的服务器控件的UniqueID匹配的值。 (2)调用LoadPostData方法,并返回bool值。 (3)如果LoadPostData方法返回true,那么调用RaisePostDataChangedEvent方法。 (4)执行RaisePostDataChangedEvent方法中定义的OnEvent方法。
2. 典型应用 下面通过一个典型实例说明处理回传数据的核心过程。创建一个自定义文本框控件WebCustomControl,其文本属性Text因回传而更改。控件在加载回传数据后引发TextChanged事件。控件类源代码如下所示:
using System;using System.Collections.Generic;using System.ComponentModel;using System.Text;using System.Web;using System.Web.UI;using System.Web.UI.WebControls;namespace WebControlLibrary{ [DefaultProperty("Text")] [ToolboxData("<{0}:WebCustomControl runat=server></{0}:WebCustomControl>")] public class WebCustomControl : WebControl, IPostBackDataHandler { // 实现Text属性 [Bindable(true)] [Category("Appearance")] [DefaultValue("")] [Localizable(true)] public string Text { get { string s = (String)ViewState["Text"]; return ((s == null) ? String.Empty : s); } set { ViewState["Text"] = value; } } //重写控件呈现方法RenderContents protected override void RenderContents(HtmlTextWriter output) { output.AddAttribute(HtmlTextWriterAttribute.Type, "text"); output.AddAttribute(HtmlTextWriterAttribute.Value, Text); output.AddAttribute(HtmlTextWriterAttribute.Name, this.UniqueID); output.RenderBeginTag(HtmlTextWriterTag.Input); output.RenderEndTag(); } //定义事件对象EventTextChanged private static readonly object EventTextChanged = new object(); #region 实现IPostBackDataHandler 成员 bool IPostBackDataHandler.LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection) { //比较初始数据presentValue和回传数据postedValue string postedValue = postCollection[postDataKey]; string presentValue = Text; if (presentValue == null || postedValue != presentValue) { Text = postedValue; return true; } return false; } void IPostBackDataHandler.RaisePostDataChangedEvent() { OnTextChanged(EventArgs.Empty); } #endregion // 实现事件处理程序OnTextChanged private void OnTextChanged(EventArgs eventArgs) { EventHandler textChangedHandler = (EventHandler)Events[EventTextChanged]; if (textChangedHandler != null) { textChangedHandler(this, eventArgs); } } // 为TextChanged实现事件属性结构 public event EventHandler TextChanged { add { Events.AddHandler(EventTextChanged, value); } remove { Events.RemoveHandler(EventTextChanged, value); } } }} 以上源代码实现了一些重要内容。 (1)控件类必须实现IPostBackDataHandler,由此可使该控件参与回传数据处理。 (2)定义属性Text,其属性值保存在ViewState中。当页面回传时,包含Text属性值的ViewState将被提交到服务器。 (3)重写RenderContents方法,并在该方法中定义控件呈现逻辑。 (4)实现IPostBackDataHandler的方法LoadPostData。比较客户端发送的数据值与先前服务器提交给客户端的数据值是否相同。如果数据相同,说明数据没有被修改,那么返回false;如果数据不同,则表明数据已经被客户端修改,则返回true。 (5)实现IPostBackDataHandler的方法RaisePostDataChangedEvent。如果LoadPostData的返回值为true,则执行该方法,即要求调用OnTextChanged方法。 (6)定义事件属性结构TextChanged。在Events事件委托列表中,为EventTextChanged事件委托对象定义Add和Remove访问器。 (7)定义OnTextChanged方法。 下面是应用自定义服务器控件的Default.aspx源代码: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %><%@ Register TagPrefix="wcl" Assembly="WebControlLibrary" Namespace="WebControlLibrary" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><script runat="server"> void demo1_TextChanged(object sender, EventArgs e) { label1.Text = "您在文本框中输入的是 " + demo1.Text; }</script><html xmlns="http://www.w3.org/1999/xhtml"><head runat="server"> <title>处理回传数据</title></head><body><form id="form1" runat="server"><div><wcl:WebCustomControl ID="demo1" runat="server" OnTextChanged="demo1_TextChanged" /><asp:Button ID="button1" runat="server" Text="提交" /> <br /><asp:Label ID="label1" runat="server" Font-Size="small"></asp:Label></div></form></body></html> 在以上代码中,定义了一个WebCustomControl控件,并为该控件定义TextChanged事件的处理方法demo1_TextChanged。该方法要求修改Label控件的Text属性值。效果图如图1和图2所示。 图1 页面初始化效果图 图2 页面提交后的效果图 可能某些读者会产生误解,以为上面的实例定义了提交按钮的Click事件的事件处理方法。实际不然。本实例并没有为提交按钮定义Click事件的处理方法,而是通过处理回传数据,并定义WebCustomControl控件的TextChanged事件来完成的。 3、小结 本文针对实现处理回传数据的实现方法进行了介绍。掌握这些内容将为开发出具有高质量的服务器控件打下良好基础。至此,通过三篇文章的介绍,相信读者已经掌握了为自定义服务器控件实现事件的基本方法。在随后的内容中,笔者将继续介绍利用ASP.NET 2.0技术创建服务器控件的其他内容。