一、概述
在web开发中,常常需要显示一些数据,而为了方便排版及浏览,我们只需要显示所有记录中的一部分。一般情况下,我们采用分页来实现这个需求。实现分页的方法多种多样,在本文中,我们采用了一个分页空间来记录记录总数、当前页、总页数及页面大小等。为了有一个直观上的印象,先展示该控件运行后的效果,效果如下图所示:

二、实现方案
为了实现该效果图,在asp.net中,可以使用Custom Controls and User Controls两种方式,User Controls的实现方式及其简单,而且使用起来和平时使用Controls的方式差别极大,所以我们采用Custom Controls实现。
参考资料:Professional ASP.NET 2.0 Server Control and Component Development
三、分页控件的实现
1)、新建一个ASP.NET Server Control项目,
2)、在该项目中添加一个ASP.NET Server Control的Item,并设置其Name为PageOn,
3)、修改该类继承于CompositeControl类,并修改其Attribute为如下所示:
[ToolboxData("<{0}:PageOn runat=server Width=100%></{0}:PageOn>")]
public class PageOn : CompositeControl
注:自定义控件必须继承自Control或者其子类。
4)、 定义需要被组合的控件
LinkButton btnFirst;
LinkButton btnPrev;
LinkButton btnNext;
LinkButton btnLast;
TextBox txtGoPage;
Button btnGo;
5)、定义分页控件需要用到的Proptery
分页控件主要包括页面大小、当前页、总记录数及总页数等属性,并需要保存在ViewState中,详细代码如下所示:

 Code
Codepublic int RowCount
{
get
{
if (ViewState["m_rowCount"] == null || int.Parse(ViewState["m_rowCount"].ToString()) < 0)
{
ViewState["m_rowCount"] = 0;
}
return int.Parse(ViewState["m_rowCount"].ToString());
}
set
{
if (value < 0)
{
ViewState["m_rowCount"] = 0;
}
else
{
ViewState["m_rowCount"] = value;
}
this.RecreateChildControls();
}
}
public int CurPage
{
get
{
if (ViewState["m_curPage"] ==null || int.Parse(ViewState["m_curPage"].ToString()) < 1)
{
ViewState["m_curPage"] = 1;
}
return int.Parse(ViewState["m_curPage"].ToString());
}
set
{
if (value < 1)
{
ViewState["m_curPage"] = 1;
}
else if (value > PageCount)
{
ViewState["m_curPage"] = PageCount;
}
else
{
ViewState["m_curPage"] = value;
}
}
}
public int PageCount
{
get
{
return RowCount / PageSize + 1;
}
}
public int PageSize
{
get
{
if (ViewState["m_pageSize"] ==null || int.Parse(ViewState["m_pageSize"].ToString()) < 1)
{
ViewState["m_pageSize"] = 15;
}
return int.Parse(ViewState["m_pageSize"].ToString());
}
set
{
if (value > 0)
{
ViewState["m_pageSize"] = value;
this.RecreateChildControls();
}
}
}
6)、生成自定义控件的子空间
生成自定义空间的子空间需要override基类Control中的CreateChildControls()方法,详细代码如下所示:

 Code
Codeprotected override void CreateChildControls()
{
Controls.Clear();
lblMessage = new Label();
lblMessage.Text = "当前第" + CurPage + "页 共" + PageCount + "页  共" + RowCount + "条记录";
lblMessage.ID = "lblMessage";
Controls.Add(lblMessage);
btnFirst = new LinkButton();
btnFirst.Text = "首页";
btnFirst.CommandName = "first";
btnFirst.ID = "btnFirst";
if (CurPage <= 1)
{
btnFirst.Enabled = false;
}
Controls.Add(btnFirst);
btnPrev = new LinkButton();
btnPrev.Text = "上一页";
btnPrev.CommandName = "prev";
btnPrev.ID = "btnPrev";
if (CurPage <= 1)
{
btnPrev.Enabled = false;
}
Controls.Add(btnPrev);
btnNext = new LinkButton();
btnNext.Text = "下一页";
btnNext.CommandName = "next";
btnNext.ID = "btnNext";
if (CurPage >= PageCount)
{
btnNext.Enabled = false;
}
Controls.Add(btnNext);
btnLast = new LinkButton();
btnLast.Text = "末页";
btnLast.CommandName = "last";
btnLast.ID = "btnLast";
if (CurPage >= PageCount)
{
btnLast.Enabled = false;
}
Controls.Add(btnLast);
txtGoPage = new TextBox();
txtGoPage.TabIndex = 1;
txtGoPage.ID = "txtGoPage";
txtGoPage.Attributes.Add("onkeyup", @"this.value=this.value.replace(/\D/g,'')");
txtGoPage.Attributes.Add("onafterpaste", @"this.value=this.value.replace(/\D/g,'')");
Controls.Add(txtGoPage);
btnGo = new Button();
btnGo.TabIndex = 2;
btnGo.CommandName = "go";
btnGo.Text = "GO";
btnGo.ID="btnGO";
Controls.Add(btnGo);
Debug.WriteLine("ffffffffffffffffffffffffffffffffffffffffffffffffff");
base.CreateChildControls();
}
7)、定义自定义控件的布局
第6步完成后,所有定义的控件都会顺序显示到页面上了,但是这样的效果不友好,如果对于多行的空间更是如此,所有我们需要定义控件的布局,自定义控件的布局需要重写RenderContents()方法及TagKey属性,此示例中的代码如下所示:

 Code
Codeprotected override void RenderContents(HtmlTextWriter output)
{
output.RenderBeginTag(HtmlTextWriterTag.Tr);
output.AddStyleAttribute("text-align", "left");
output.RenderBeginTag(HtmlTextWriterTag.Td);
output.Write("  ");
lblMessage.RenderControl(output);
output.RenderEndTag();
output.AddStyleAttribute("text-align", "right");
output.RenderBeginTag(HtmlTextWriterTag.Td);
btnFirst.RenderControl(output);
output.Write("  ");
btnPrev.RenderControl(output);
output.Write("  ");
btnNext.RenderControl(output);
output.Write("  ");
btnLast.RenderControl(output);
output.Write("到");
output.AddStyleAttribute(HtmlTextWriterStyle.Width, "30px");
txtGoPage.RenderControl(output);
output.Write("页");
btnGo.RenderControl(output);
output.Write("  ");
output.RenderEndTag();
output.RenderEndTag();
}
protected override HtmlTextWriterTag TagKey
{
get
{
return HtmlTextWriterTag.Table;
}
}
上面的代码中,我们使用Table来布局,也可以使用其它的布局方式,比如DIV+CSS。
8)、捕捉并处理控件的事件
到此以后,这些代码已经可以生成文章开头图所显示的效果,但是什么事情也做不了,不能响应该控件上的事件,所有还需要继续实现该控件上的事件代码,实现这些事件采用冒泡所有子控件的事件来实现。
首先,定义一个委托:
最后,重写冒泡事件,并根据参数特征,捕获需要处理的事件,使其调用需要的方法。

 Code
Codeprotected override bool OnBubbleEvent(object source, EventArgs args)
{
bool handled = false;
CommandEventArgs cea = args as CommandEventArgs;
if(cea == null)
{
return handled;
}
switch (cea.CommandName)
{
case "first":
handled = true;
CurPage = 1;
break;
case "prev":
handled = true;
if (CurPage > 1)
{
CurPage--;
}
else
{
CurPage = 1;
}
break;
case "next":
handled = true;
if (CurPage < PageCount)
{
CurPage ++ ;
}
else
{
CurPage = PageCount;
}
break;
case "last":
handled = true;
CurPage = PageCount;
break;
case "go":
string strGo = txtGoPage.Text.Trim();
int iGo;
if (!string.IsNullOrEmpty(strGo) && int.TryParse(strGo, out iGo))
{
handled = true;
CurPage = iGo;
}
break;
}
if (handled)
{
if (this.RecPageChanged != null)
{
RecPageChanged(this, args);
this.RecreateChildControls();
}
return handled;
}
else
{
return base.OnBubbleEvent(source, args);
}
}
到此就完成了分页控件的开发。
注:可以定制该控件的样式,或者使用属性暴露子控件的属性来控制样式等.
四、使用分页控件
完成自定义控件的开发后,在Toolbox中Choose Items或者直接在需要使用该自定义控件的项目中引用该项目或者DLL,即可在Toolbox中显示自定义控件了。然后用拖拽的方式即可把分页控件放到需要的地方,就像使用button控件一样简单。
然后再该页面的后台代码的OnLoad事件中,注册需要被调用的方法到该控件的RecPageChanged事件中,如下所示:
最后,只需要在方法PageOn1_RecPageChanged中编写自己的代码即可。
{
//To do something
}
控件的详细代码如下:

 Code
Code namespace CustomControl
namespace CustomControl

 {
{ public delegate void PageOnEventHandler(object sender, EventArgs args);
    public delegate void PageOnEventHandler(object sender, EventArgs args);
 [DefaultProperty("PageSize")]
    [DefaultProperty("PageSize")] [ToolboxData("<{0}:PageOn runat=server Width=100%></{0}:PageOn>")]
    [ToolboxData("<{0}:PageOn runat=server Width=100%></{0}:PageOn>")] public class PageOn :CompositeControl
    public class PageOn :CompositeControl
 
     {
{

 
         #region
#region 
 Label lblMessage;
        Label lblMessage;
 LinkButton btnFirst;
        LinkButton btnFirst; LinkButton btnPrev;
        LinkButton btnPrev; LinkButton btnNext;
        LinkButton btnNext; LinkButton btnLast;
        LinkButton btnLast;
 TextBox txtGoPage;
        TextBox txtGoPage;
 Button btnGo;
        Button btnGo;
 #endregion
        #endregion
 protected override void CreateChildControls()
        protected override void CreateChildControls()
 
         {
{ Controls.Clear();
            Controls.Clear();
 lblMessage = new Label();
            lblMessage = new Label(); lblMessage.Text = "当前第" + CurPage + "页 共" + PageCount + "页  共" + RowCount + "条记录";
            lblMessage.Text = "当前第" + CurPage + "页 共" + PageCount + "页  共" + RowCount + "条记录"; lblMessage.ID = "lblMessage";
            lblMessage.ID = "lblMessage"; Controls.Add(lblMessage);
            Controls.Add(lblMessage);
 btnFirst = new LinkButton();
            btnFirst = new LinkButton(); btnFirst.Text = "首页";
            btnFirst.Text = "首页"; btnFirst.CommandName = "first";
            btnFirst.CommandName = "first"; btnFirst.ID = "btnFirst";
            btnFirst.ID = "btnFirst"; if (CurPage <= 1)
            if (CurPage <= 1)
 
             {
{ btnFirst.Enabled = false;
                btnFirst.Enabled = false; }
            } Controls.Add(btnFirst);
            Controls.Add(btnFirst);
 btnPrev = new LinkButton();
            btnPrev = new LinkButton(); btnPrev.Text = "上一页";
            btnPrev.Text = "上一页"; btnPrev.CommandName = "prev";
            btnPrev.CommandName = "prev"; btnPrev.ID = "btnPrev";
            btnPrev.ID = "btnPrev"; if (CurPage <= 1)
            if (CurPage <= 1)
 
             {
{ btnPrev.Enabled = false;
                btnPrev.Enabled = false; }
            } Controls.Add(btnPrev);
            Controls.Add(btnPrev);
 btnNext = new LinkButton();
            btnNext = new LinkButton(); btnNext.Text = "下一页";
            btnNext.Text = "下一页"; btnNext.CommandName = "next";
            btnNext.CommandName = "next"; btnNext.ID = "btnNext";
            btnNext.ID = "btnNext"; if (CurPage >= PageCount)
            if (CurPage >= PageCount)
 
             {
{ btnNext.Enabled = false;
                btnNext.Enabled = false; }
            } Controls.Add(btnNext);
            Controls.Add(btnNext);
 btnLast = new LinkButton();
            btnLast = new LinkButton(); btnLast.Text = "末页";
            btnLast.Text = "末页"; btnLast.CommandName = "last";
            btnLast.CommandName = "last"; btnLast.ID = "btnLast";
            btnLast.ID = "btnLast"; if (CurPage >= PageCount)
            if (CurPage >= PageCount)
 
             {
{ btnLast.Enabled = false;
                btnLast.Enabled = false; }
            } Controls.Add(btnLast);
            Controls.Add(btnLast);
 txtGoPage = new TextBox();
            txtGoPage = new TextBox(); txtGoPage.TabIndex = 1;
            txtGoPage.TabIndex = 1; txtGoPage.ID = "txtGoPage";
            txtGoPage.ID = "txtGoPage"; txtGoPage.Attributes.Add("onkeyup", @"this.value=this.value.replace(/\D/g,'')");
            txtGoPage.Attributes.Add("onkeyup", @"this.value=this.value.replace(/\D/g,'')"); txtGoPage.Attributes.Add("onafterpaste", @"this.value=this.value.replace(/\D/g,'')");
            txtGoPage.Attributes.Add("onafterpaste", @"this.value=this.value.replace(/\D/g,'')"); Controls.Add(txtGoPage);
            Controls.Add(txtGoPage);
 btnGo = new Button();
            btnGo = new Button(); btnGo.TabIndex = 2;
            btnGo.TabIndex = 2; btnGo.CommandName = "go";
            btnGo.CommandName = "go"; btnGo.Text = "GO";
            btnGo.Text = "GO"; btnGo.ID="btnGO";
            btnGo.ID="btnGO"; Controls.Add(btnGo);
            Controls.Add(btnGo);
 Debug.WriteLine("ffffffffffffffffffffffffffffffffffffffffffffffffff");
            Debug.WriteLine("ffffffffffffffffffffffffffffffffffffffffffffffffff"); base.CreateChildControls();
            base.CreateChildControls(); }
        }

 public int RowCount
        public int RowCount
 
         {
{ get
            get
 
             {
{ if (ViewState["m_rowCount"] == null || int.Parse(ViewState["m_rowCount"].ToString()) < 0)
                if (ViewState["m_rowCount"] == null || int.Parse(ViewState["m_rowCount"].ToString()) < 0)
 
                 {
{ ViewState["m_rowCount"] = 0;
                    ViewState["m_rowCount"] = 0; }
                } return int.Parse(ViewState["m_rowCount"].ToString());
                return int.Parse(ViewState["m_rowCount"].ToString()); }
            } set
            set
 
             {
{ if (value < 0)
                if (value < 0)
 
                 {
{ ViewState["m_rowCount"] = 0;
                    ViewState["m_rowCount"] = 0; }
                } else
                else
 
                 {
{ ViewState["m_rowCount"] = value;
                    ViewState["m_rowCount"] = value; }
                } this.RecreateChildControls();
                this.RecreateChildControls(); }
            } }
        }
 public int CurPage
        public int CurPage
 
         {
{ get
            get
 
             {
{ if (ViewState["m_curPage"] ==null || int.Parse(ViewState["m_curPage"].ToString()) < 1)
                if (ViewState["m_curPage"] ==null || int.Parse(ViewState["m_curPage"].ToString()) < 1)
 
                 {
{ ViewState["m_curPage"] = 1;
                    ViewState["m_curPage"] = 1; }
                } return int.Parse(ViewState["m_curPage"].ToString());
                return int.Parse(ViewState["m_curPage"].ToString()); }
            } set
            set
 
             {
{ if (value < 1)
                if (value < 1)
 
                 {
{ ViewState["m_curPage"] = 1;
                    ViewState["m_curPage"] = 1; }
                } else if (value > PageCount)
                else if (value > PageCount)
 
                 {
{ ViewState["m_curPage"] = PageCount;
                    ViewState["m_curPage"] = PageCount; }
                } else
                else
 
                 {
{ ViewState["m_curPage"] = value;
                    ViewState["m_curPage"] = value; }
                } }
            } }
        }
 public int PageCount
        public int PageCount
 
         {
{ get
            get
 
             {
{ return RowCount / PageSize + 1;
                return RowCount / PageSize + 1; }
            } }
        }
 public int PageSize
        public int PageSize
 
         {
{ get
            get
 
             {
{ if (ViewState["m_pageSize"] ==null || int.Parse(ViewState["m_pageSize"].ToString()) < 1)
                if (ViewState["m_pageSize"] ==null || int.Parse(ViewState["m_pageSize"].ToString()) < 1)
 
                 {
{ ViewState["m_pageSize"] = 15;
                    ViewState["m_pageSize"] = 15; }
                } return int.Parse(ViewState["m_pageSize"].ToString());
                return int.Parse(ViewState["m_pageSize"].ToString()); }
            } set
            set
 
             {
{ if (value > 0)
                if (value > 0)
 
                 {
{ ViewState["m_pageSize"] = value;
                    ViewState["m_pageSize"] = value; this.RecreateChildControls();
                    this.RecreateChildControls(); }
                } }
            } }
        }


 protected override void RenderContents(HtmlTextWriter output)
        protected override void RenderContents(HtmlTextWriter output)
 
         {
{             output.RenderBeginTag(HtmlTextWriterTag.Tr);
            output.RenderBeginTag(HtmlTextWriterTag.Tr);
 output.AddStyleAttribute("text-align", "left");
            output.AddStyleAttribute("text-align", "left"); output.RenderBeginTag(HtmlTextWriterTag.Td);
            output.RenderBeginTag(HtmlTextWriterTag.Td); output.Write("  ");
            output.Write("  "); lblMessage.RenderControl(output);
            lblMessage.RenderControl(output); output.RenderEndTag();
            output.RenderEndTag();
 output.AddStyleAttribute("text-align", "right");
            output.AddStyleAttribute("text-align", "right"); output.RenderBeginTag(HtmlTextWriterTag.Td);
            output.RenderBeginTag(HtmlTextWriterTag.Td); btnFirst.RenderControl(output);
            btnFirst.RenderControl(output); output.Write("  ");
            output.Write("  "); btnPrev.RenderControl(output);
            btnPrev.RenderControl(output); output.Write("  ");
            output.Write("  "); btnNext.RenderControl(output);
            btnNext.RenderControl(output); output.Write("  ");
            output.Write("  "); btnLast.RenderControl(output);
            btnLast.RenderControl(output); output.Write("到");
            output.Write("到"); output.AddStyleAttribute(HtmlTextWriterStyle.Width, "30px");
            output.AddStyleAttribute(HtmlTextWriterStyle.Width, "30px"); txtGoPage.RenderControl(output);
            txtGoPage.RenderControl(output); output.Write("页");
            output.Write("页");
 btnGo.RenderControl(output);
            btnGo.RenderControl(output); 
             output.Write("  ");
            output.Write("  "); output.RenderEndTag();
            output.RenderEndTag();
 output.RenderEndTag();
            output.RenderEndTag(); }
        }
 protected override HtmlTextWriterTag  TagKey
        protected override HtmlTextWriterTag  TagKey
 
         {
{ get
            get
 
             {
{ return HtmlTextWriterTag.Table;
                return HtmlTextWriterTag.Table; }
            } }
        }
 public event PageOnEventHandler RecPageChanged;
        public event PageOnEventHandler RecPageChanged;
 protected override bool OnBubbleEvent(object source, EventArgs args)
        protected override bool OnBubbleEvent(object source, EventArgs args)
 
         {
{ bool handled = false;
            bool handled = false;
 CommandEventArgs cea = args as CommandEventArgs;
            CommandEventArgs cea = args as CommandEventArgs; if(cea == null)
            if(cea == null)
 
             {
{ return handled;
                return handled; }
            } switch (cea.CommandName)
            switch (cea.CommandName)
 
             {
{ case "first":
                case "first": handled = true;
                    handled = true; CurPage = 1;
                    CurPage = 1; break;
                    break; case "prev":
                case "prev": handled = true;
                    handled = true; if (CurPage > 1)
                    if (CurPage > 1)
 
                     {
{ CurPage--;
                        CurPage--; }
                    } else
                    else
 
                     {
{ CurPage = 1;
                        CurPage = 1; }
                    } break;
                    break; case "next":
                case "next": handled = true;
                    handled = true; if (CurPage < PageCount)
                    if (CurPage < PageCount)
 
                     {
{ CurPage ++ ;
                        CurPage ++ ; }
                    } else
                    else
 
                     {
{ CurPage = PageCount;
                        CurPage = PageCount; }
                    } break;
                    break; case "last":
                case "last": handled = true;
                    handled = true; CurPage = PageCount;
                    CurPage = PageCount; break;
                    break; case "go":
                case "go": string strGo = txtGoPage.Text.Trim();
                    string strGo = txtGoPage.Text.Trim(); int iGo;
                    int iGo; if (!string.IsNullOrEmpty(strGo) && int.TryParse(strGo, out iGo))
                    if (!string.IsNullOrEmpty(strGo) && int.TryParse(strGo, out iGo))
 
                     {
{ handled = true;
                        handled = true; CurPage = iGo;
                        CurPage = iGo; }
                    } break;
                    break; }
            }
 if (handled)
            if (handled)
 
             {
{ if (this.RecPageChanged != null)
                if (this.RecPageChanged != null)
 
                 {
{ RecPageChanged(this, args);
                    RecPageChanged(this, args); this.RecreateChildControls();
                    this.RecreateChildControls(); }
                } return handled;
                return handled; }
            } else
            else
 
             {
{ return base.OnBubbleEvent(source, args);
                return base.OnBubbleEvent(source, args); }
            } }
        }
 }
    } }
}OK,The End。。。
 
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号