先搞清楚几个概念:
回传:PostBack,ASP.NET控件提交表单到服务器端,将信息从浏览器传递到服务器端。是一个过程。
当ASP.NET页面处理回传到服务器端的表单时,两种信息会传递给页面中的控件,一个是回传事件,如Button一类控件触发的回传,会引发服务器端事件;另一个回传数据:是Web表单中包含的数据,该数据是在Web表单提交到服务器端时传递给如TextBox一类的控件。
3.1处理回传数据
如果控件要处理提交回服务器端的表单数据,需要实现IPostBackDataHandler接口,该接口包含两个方法:
LoadPostData()——检索从浏览器传回到服务器的数据或者是表单域
RasisePostDataChangedEvent——引发一个事件:该事件用于处理控件或者表单域的值发生改变。
代码示例:CustomTextBox.cs

Code
using System;
using System.Collections.Generic;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace JerryShi.Controls


{
public class CustomTextBox : WebControl, IPostBackDataHandler

{
public event EventHandler TextChanged;

public string ViewText

{
get

{
if (ViewState["Text"].Equals(null))

{
return String.Empty;
}
else

{
return ViewState["Text"].ToString();
}
}
set

{
ViewState["Text"] = value;
}
}

protected override HtmlTextWriterTag TagKey

{
get

{
return HtmlTextWriterTag.Input;
}
}

protected override void AddAttributesToRender(HtmlTextWriter writer)

{
writer.AddAttribute(HtmlTextWriterAttribute.Type, "text");
writer.AddAttribute(HtmlTextWriterAttribute.Value, ViewText);
writer.AddAttribute(HtmlTextWriterAttribute.Name, this.UniqueID);

base.AddAttributesToRender(writer);
}


IPostBackDataHandler 成员#region IPostBackDataHandler 成员

//postDataKey表示关联到当前控件的域的名字
public bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection)

{
if (postCollection[postDataKey] != ViewText)

{
ViewText = postCollection[postDataKey];
return true;
}
return false;
}

public void RaisePostDataChangedEvent()

{
if (TextChanged != null)
TextChanged(this, EventArgs.Empty);
}

#endregion
}
}

注:
LoadPostData所实现的操作:如果该控件表单域的值发生了改变,即:表单域的值和控件的ViewText(此示例中)属性的当前值不匹配,那么将新的值赋给ViewText属性,并且返回True。只有当LoadPostData返回True的时候,才会调用RaisePostDataChangedEvent方法。
如果控件生成的表单域的名字和控件的名字不匹配,需要通知包含该控件的页面,将表单域的数据传给该控件。可以在Control的PreRender()事件中获之前,在InitCompleted()事件之后,调用Page.RegisterRquiresPostBack()方法,通知页面该控件需要接收回传数据。即:如果发现Control的LoadPostData()从未被调用,可以通过在控件中调用Page.RegisterRequiresPostBack()方法,来强制其执行。
在创建自定义javascript控件时,一般都需要实现IPostBackDataHandler接口。从javascript控件传递数据到服务器端的常用做法是使用隐藏表单域,可以通过使用IPostBackDataHandler接口来处理隐藏表单域的内容,之后的章节会用到。
3.2处理回传事件
每次由一个服务器端控件引起回传,同时引发回传事件。为了处理回传事件,需要实现IPostBackEventHandler接口,该接口包括一个方法:
·RaisePostBackEvent()——当控件引发回传时在服务器端调用
代码示例:CustomLinkButton.cs
Page.ClientScript.GetPostBackClientHyperLinl()方法返回引起表单回传的javascript字符串,将该字符串赋给一个HtmlTextWriterAttribute.Href中,则该链接可以引起表单回传。
该字符串为:javascript:_doPostBack(“”,””)
与该方法相似的另外一个方法:GetPostBackEventReference();这二者的区别在于:GetPostBackClientHyperLink()返回的js字符串包含“javascript:”前缀,而GetPostBackEventReference()不包含。
·可以为GetPostBackClientHyperLink()提供一个可选的参数,该参数在引发回传时,从客户端传到服务器端的RaisePostBackEvent()方法。
假定创建一个和GridView控件一起使用的自定义分页控件,该控件用于显示页码列表,可以点击它来导航到GridView显示记录的某一页。为创建该控件,需要生成多个引发回传事件的链接。
代码示例:Pager.cs

Code
using System;
using System.Collections.Generic;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace JerryShi.Controls


{
public class Pager:WebControl,IPostBackEventHandler

{
private string _controlToPage;

public string ControlToPage

{

get
{ return _controlToPage; }

set
{ _controlToPage = value; }
}

private GridView GetControlFromPage()

{
if (String.IsNullOrEmpty(_controlToPage))

{
throw new Exception("Must set ControlToPage property");
}
return (GridView)Page.FindControl(_controlToPage);
}

protected override void RenderContents(HtmlTextWriter writer)

{
GridView m_gridview = GetControlFromPage();

for (int index = 0; index < m_gridview.PageCount; index++)

{
string eRef = Page.ClientScript.GetPostBackClientHyperlink(this, index.ToString());
writer.Write("[");
if (index == m_gridview.PageIndex)

{
writer.AddStyleAttribute(HtmlTextWriterStyle.FontWeight, "bold");
}
writer.AddAttribute(HtmlTextWriterAttribute.Href, eRef);
writer.RenderBeginTag(HtmlTextWriterTag.A);
writer.Write("{0}", index + 1);
writer.RenderEndTag();
writer.Write("]");
}
}


IPostBackEventHandler 成员#region IPostBackEventHandler 成员

public void RaisePostBackEvent(string eventArgument)

{
GridView m_gridview = GetControlFromPage();
m_gridview.PageIndex = Int32.Parse(eventArgument);
}

#endregion
}
}

当点击页面链接时,关联的页码传回到服务器端,RaisePostBackEvent()方法接受这个参数并更改关联的GridView所显示的分页。
3.3回传选项
要在自定义空间中实现像跨页提交、验证组、以及编程控制控件焦点等等高级特性,需要指定高级的回传选项。
使用PostBackOptions类来指定高级回传选项。
ActionUrl——用于指定表单提交的页面
Argument——用于指定回传参数
AutoPostBack——用于添加实现AutoPostBack事件必须的javascript
ClientSubmit——用于通过客户端脚本引发回传
PerformValidation——用于指定是否执行验证(通过CausesValidation属性设置)
RequiresJavaScriptProtocol——用于生成javascript:前缀
TargetControl——用于指定响应引发的回传的控件
TrackFocus——用于回传后滚动页面回到当前滚动位置并把焦点返回给控件
ValidationGroup——用于指定该控件关联的验证组
代码示例:AdvancedCheckBox.cs

Code
using System;
using System.Web.UI;
using System.Web.UI.WebControls;


namespace JerryShi.Controls


{
public class AdvancedCheckBox : WebControl

{
private string _Text;
private string _PostBackUrl;

public string Text

{

get
{ return _Text; }

set
{ _Text = value; }
}
public string PostBackUrl

{

get
{ return _PostBackUrl; }

set
{ _PostBackUrl = value; }
}

protected override HtmlTextWriterTag TagKey

{
get

{
return HtmlTextWriterTag.Input;
}
}

protected override void AddAttributesToRender(HtmlTextWriter writer)

{
PostBackOptions options = new PostBackOptions(this);
options.ActionUrl = _PostBackUrl;
options.Argument = "customargument";
options.AutoPostBack = false;
options.PerformValidation = false;

string eRef = Page.ClientScript.GetPostBackEventReference(options);

writer.AddAttribute(HtmlTextWriterAttribute.Onclick, eRef);
writer.AddAttribute(HtmlTextWriterAttribute.Name, this.UniqueID);
writer.AddAttribute(HtmlTextWriterAttribute.Type, "checkbox");

base.AddAttributesToRender(writer);
}

protected override void RenderContents(HtmlTextWriter writer)

{
if (!String.IsNullOrEmpty(_Text))

{
writer.AddAttribute(HtmlTextWriterAttribute.For, this.ClientID);
writer.RenderBeginTag(HtmlTextWriterTag.Label);
writer.Write(_Text);
writer.RenderEndTag();
}
}
}
}

创建一个高级复选框,点击该复选框,表单数据提交到PostBackUrl属性指定的页面,支持跨页提交。