在实际应用中,经常需要在客户端输入时选择一下类别,这个类别经常会是大类和小类,以前在ASP中实现的时候是全部读取出来,再通过javascript来实现点击大类后小类列表更新,在.net2.0里,通过客户端回调就可以实现这种功能。
我的实际应用例子之一:页面名称是setType.aspx,以下是代码片段,这个是客户端显示的页面
<asp:Content ID="Content1" ContentPlaceHolderID="mainTable" Runat="Server">
<script language="javascript" type="text/javascript">
function CallServer(arg, context)
{
context.innerHTML = "Loading";
<%= ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", "context") %>;
}
function ReceiveServerData(result, context)
{
context.innerHTML = result;
}
</script>
设置类别:<asp:DropDownList ID="ddlLeibie" runat="server">
</asp:DropDownList>
<span id="_span1">
<asp:DropDownList ID="ddlSmall" runat="server">
</asp:DropDownList>
<asp:Button ID="btnSet" runat="server" Text="设置" Width="113px" /></span>
</asp:Content>
代码文件:setType.aspx.cs
需要有以下几个引用
using System.IO;
using System.Globalization;
using System.Reflection;
并且此文件类的基类有两个,public partial class webAdmin_setType : System.Web.UI.Page, System.Web.UI.ICallbackEventHandler
要实现回调就需继承ICallbackEventHandler类并重写其中的两个方法GetCallbackResult()和RaiseCallbackEvent()
代码详细如下:
public partial class webAdmin_setType : System.Web.UI.Page, System.Web.UI.ICallbackEventHandler
{
private string _callbackEventArgument;
protected void Page_Load(object sender, EventArgs e)
{
ddlLeibie.Attributes.Add("onchange", "CallServer('FillLeibie|'+this.value,_span1)");
Initpage();
}
#region ICallbackEventHandler Members
/// <summary>
/// 获取回调的参数,通过分析字符串,得出将在服务器端使用的方法(FillLeibie()),并在使用过该方法后返回值到客户端,返回一段HTML代码重写列表
/// </summary>
/// <returns></returns>
public string GetCallbackResult()
{
string[] parts = _callbackEventArgument.Split('|');
object[] args = null;
string result = "";
if (parts.Length > 1)
{
args = new object[parts.Length - 1];
Array.Copy(parts, 1, args, 0, args.Length);
}
MethodInfo method = this.GetType().GetMethod(parts[0]);
if (method != null)
{
result = (string)method.Invoke(this, args);
}
return result;
}
/// <summary>
/// 获取从客户端提交的需调用服务器方法的信息,并赋值给一私有字段,再通过GetCallbackResult来分析该字段。
/// </summary>
/// <param name="eventArgument"></param>
public void RaiseCallbackEvent(string eventArgument)
{
_callbackEventArgument = eventArgument;
}
void ICallbackEventHandler.RaiseCallbackEvent(string eventArgument)
{
this.RaiseCallbackEvent(eventArgument);
}
string ICallbackEventHandler.GetCallbackResult()
{
return this.GetCallbackResult();
}
#endregion
public string FillLeibie(string lid)
{
ddlSmall.Items.Clear();
FenLei f = new FenLei();
ArrayList small=f.GetSmall(lid);
char[] s ={ '|' };
for (int i = 0; i < small.Count; i++)
{
string[] ss = small[i].ToString().Split(s);
System.Web.UI.WebControls.ListItem a = new ListItem(ss[1], ss[0]);
ddlSmall.Items.Add(a);
}
return RenderControl(ddlSmall);
}
private string RenderControl(Control control)
{
StringWriter writer1 = new StringWriter(CultureInfo.InvariantCulture);
HtmlTextWriter writer2 = new HtmlTextWriter(writer1);
control.RenderControl(writer2);
writer2.Flush();
writer2.Close();
return writer1.ToString();
}
private void Initpage()
{
FenLei f=new FenLei();
ArrayList leibie=f.GetLeibie();
char[] s ={ '|' };
ddlLeibie.Items.Add(new ListItem("请选择大类", "0"));
for (int i = 0; i < leibie.Count; i++)
{
string[] ss = leibie[i].ToString().Split(s);
System.Web.UI.WebControls.ListItem a = new ListItem(ss[1], ss[0]);
ddlLeibie.Items.Add(a);
}
ddlSmall.Items.Add(new ListItem("请先选择大类", "0"));
}
}
我的功能已经实现,在客户端不需刷新页面,就可以实时更新数据了,这有点像XMLHTTP