** 动态加载 Asp.net ** ** 分页控件 **
郑佐 2004-11-30
** ** 在 asp.net 中动态加载控件比较简单,这里我讲得是对用户控件的加载,比较典型的就是被加载的用户控件里面包含回发事件,在回传回来的时候需要保持新的数据。
先来构建分页用户控件,由于前面几篇文章都在讲这些东西,所以就直接拿过来改了改,分页代码可以查看上面的 文章 1 , 文章 2 ,下面是用户控件的一部分代码。
public class PagingControl : System.Web.UI.UserControl
{
private int pageCount;
private int recordCount;
……
private void Page_Load( object sender, System.EventArgs e)
{
if (!Page.IsPostBack)
{
DataGridDataBind();
}
}
// 绑定数据
private void DataGridDataBind()
{
DataSet ds = GetCustomersData(PageIndex,PageSize, ref recordCount, ref pageCount);
this .DataGrid1.VirtualItemCount = RecordCount;
this .DataGrid1.DataSource = ds;
this .DataGrid1.DataBind();
SetPagingState();
}
// 绑定新的页面
private void LBtnNavigation_Click( object sender, System.EventArgs e)
{
LinkButton btn = (LinkButton)sender;
switch (btn.CommandName)
{
case "First":
PageIndex = 0;
break ;
case "Prev":
PageIndex = PageIndex - 1;
break ;
case "Next":
PageIndex = PageIndex + 1;
break ;
case "Last":
PageIndex = PageCount - 1;
break ;
}
DataGridDataBind();
}
……
}
在上面我们注意到在页面 Load 事件中判断 if (!Page.IsPostBack) 来防止在回发加载的时候进行两次绑定,因为第一次完全没有必要,最终由 LBtnNavigation_Click 中的绑定决定。
假设 PagingControl.ascx 为上面的用户控件的文件名,而且同 Page 页面文件在同一目录,下面是 AspnetCommonPaging.aspx 文件的代码,为了动态加载,在页面上放了一个 PlaceHolder 控件来加载先前的用户控件。
前台文件如下:
1@ Page language="c#" Codebehind="AspnetCommonPaging.aspx.cs" AutoEventWireup="false" Inherits="AspnetPaging.AspnetCommonPaging"
1<html>
2<head>
3<title>AspnetCommonPaging</title>
4</head>
5<body>
6<form id="Form1" method="post" runat="server">
7<asp:placeholder id="PlaceHolder1" runat="server"></asp:placeholder>
8</form>
9</body>
10</html>
后台代码文件也比较简单:
namespace AspnetPaging
{
public class AspnetCommonPaging : System.Web.UI.Page
{
protected System.Web.UI.WebControls.PlaceHolder PlaceHolder1;
private void Page_Load( object sender, System.EventArgs e)
{
PlaceHolder1.Controls.Add(Page.LoadControl("~/PagingControl.ascx"));
}
#region Web 窗体设计器生成的代码
override protected void OnInit(EventArgs e)
{
InitializeComponent();
base .OnInit(e);
}
///
1<summary>
2
3/// 设计器支持所需的方法 \- 不要使用代码编辑器修改
4
5/// 此方法的内容。
6
7/// </summary>
private void InitializeComponent()
{
this .Load += new System.EventHandler( this .Page_Load);
}
#endregion
}
}
这里的 PlaceHolder1.Controls.Add(Page.LoadControl("~/PagingControl.ascx")); 就是把 PagingControl 用户控件载到当前页面上来。如果不想用 PlaceHolder ,我们也可以使用其他容器控件,只要添加到 Controls 集合就行了。
注意这里如果按下面这样处理,那面在页面回发的时候就会不被加载,那么也就不会触发分页事件。
private void Page_Load( object sender, System.EventArgs e)
{
if (!Page.IsPostBack)
PlaceHolder1.Controls.Add(Page.LoadControl("~/PagingControl.ascx"));
}
现在让我们来看看主要事件的执行顺序:设置断点,得到下面的顺序。
第一次:页面 OnInit 事件 --> 页面 Page_Load 事件 à 控件 OnInit 事件 à 控件 Page_Load 事件。
翻页回发:页面 OnInit 事件 --> 页面 Page_Load 事件 à 控件 OnInit 事件 à 控件 Page_Load 事件 à LBtnNavigation_Click 翻页事件。
如果我们把页面加载代码放在 页面 OnInit 事件:
override protected void OnInit(EventArgs e)
{
InitializeComponent();
PlaceHolder1.Controls.Add(Page.LoadControl("~/PagingControl.ascx"));
base .OnInit(e);
}
那么事件的执行顺序会是什么样呢?
第一次:页面 OnInit 事件 --> 控件 OnInit 事件 à 页面 Page_Load 事件 à 控件 Page_Load 事件。
翻页回发:页面 OnInit 事件 --> 控件 OnInit 事件 à 页面 Page_Load 事件 à 控件 Page_Load 事件 à LBtnNavigation_Click 翻页事件。
我认为对于多控件的互操作,清楚事件的执行顺序是很重要的,另外也有助于优化程序提高性能。