先搞清楚几个概念:
回传: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属性指定的页面,支持跨页提交。