呵呵!今天午觉没睡好,感觉太热了,睡了一下子就热醒了,同事们都不吹空调了,没办法! 现在已经是上班时间了,但一点也不想做事,再加上没睡好,头晕晕的,跑到洗手间用冷水洗 一把脸,回到办公桌前,就想到先写篇BLOG吧,昨天写了一个分页控件,把它写到自己的BLOG 上去,呵呵!其实这个控件之前是我同事写的,昨天闲得无聊,就想到把同事那个控件改进一下 吧,我觉得搞得太复杂了(按钮太多、、、,我自认为不需要那些东东) 我同事把这个控件称之为“无源虚拟分页控件”因为它是不需要数据源的,只起到虚拟选择页 号与定位的作用,只需要指定其TotalRecord (记录总数)就可以帮你虚拟分页了. 控件的按钮支持文字和图片俩种格式,可以设定其版页最大显示数,每页显示记录数,以及鼠标 放在按钮上的提示信息. 由于是无源虚拟分页,所以控件必须给定TotalRecord (记录总数)以及实现ChangePageClick事件 那么记录的总数怎么出来呢,那当然是通过存储过程来取得了,这个存储过程必须是每次取得的数据 是当前展示所需要的(也就是说取当前页的记录),如果一股脑儿把所有满足条件的数据全取出来 那根本就没有意义了,所以呢,要实现分页这个存储过程也是很重要的。 下面是我做DEMO的存储过程
set ANSI_NULLS ON set QUOTED_IDENTIFIER ON go -- ============================================= -- Author: <不懂> -- Create date: <2006-11-8> -- Description: <分页存储过程> -- ============================================= ALTER PROCEDURE [ dbo ] . [ P_PageRecord ] (@intPageSize int = 10 , @intPageNum int = 1 , @strWhere nvarchar ( 200 )) AS BEGIN SET NOCOUNT ON ; if ( @intPageSize < 2 or @intPageSize > 100 ) set @intPageSize = 10 if ( @intPageNum < 1 ) set @intPageNum = 1 ; WITH Search(OrderID,CustomerID,EmployeeID,OrderDate,RequiredDate,ShippedDate , ShipVia ,Freight ,ShipName,RowNum) as ( select OrderID , CustomerID, EmployeeID , OrderDate, RequiredDate, ShippedDate , ShipVia , Freight , ShipName, ROW_NUMBER() over ( order by OrderID DESC ) as RowNum from Orders where ShipAddress like N ' % ' + @strWhere + N ' % ' ) SELECT OrderID,CustomerID,EmployeeID,OrderDate,RequiredDate,ShippedDate , ShipVia ,Freight ,ShipName,( select count ( * ) from Search) as Rows from Search where RowNum > @intPageSize * ( @intPageNum - 1 ) and RowNum <= @intPageSize * @intPageNum SET NOCOUNT OFF ; return @@ERROR END
这个分页控件是个完全自定义的控件没有UI的,继承于WebControl,为了响应事件还得继承IPostBackEventHandler,下面就是完整的实现代码。
using System; using System.Collections.Generic; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.HtmlControls; using System.ComponentModel; using System.Text; [assembly: TagPrefix( " SmbComponent " , " BG " )] namespace SmbComponent { /**/ /// <summary> /// 作者:不懂 /// 日期:2006-11-8 /// </summary> [DefaultProperty( " TotalRecord " ), DefaultEvent( " ChangePageClick " ), ToolboxData( " <{0}:PageList runat=server></{0}:PageList> " )] public class PageList:WebControl,IPostBackEventHandler { 公用变量 #region 公用变量 private int _iTotalRecord = 0 ; // 记录总数 private int _iPageSize = 10 ; // 页码大小 private int _iItemSize = 10 ; // 页规格 private int _iCurrentPage = 1 ; // 当前页码 private int _iTotalPage = 0 ; // 总页数 #endregion 导航图片路径及相关变量 #region 导航图片路径及相关变量 private string _strPrevICON = string .Empty; // 上一页图片 private string _strNextICON = string .Empty; // 下一页图片 private string _strCurrColor = " #CC0000 " ; // 当前选择页码颜色 private string _strLinkColor = " #0000C0 " ; // 字休颜色 private string _strCssClass = " none " ; // 控件样式表 private string _strPrevTitle = " 上一页 " ; // 上一页按钮显示的文字 private string _strNextTitle = " 下一页 " ; // 下一页按钮显示的文字 private string _strPrevMessage = "" ; // 上一页的提示信息 private string _strNextMessage = "" ; // 下一页的提示信息 private string _strPageNOMessage = " 点击跳转到第: " ; // 鼠标放在按钮上显示的文字 private PageButtonStyle pageButtonStyel = PageButtonStyle.Text; #endregion 枚举 #region 枚举 /**/ /// <summary> /// 分页控件按钮类型 /// </summary> public enum PageButtonStyle { Text, // 文字 Picture // 图片 } #endregion 属性 #region 属性 总记录数 #region 总记录数 [Description(" 记录总数 " ),Bindable( true ),Category( " Appearance " ),DefaultValue( 0 )] public int TotalRecord { get { return _iTotalRecord; } set { foreach ( char c in System.Convert.ToString(value)) { if ( ! Char.IsNumber(c)) { _iTotalRecord = 0 ; break ; } } _iTotalRecord = value; } } #endregion 页码大小 #region 页码大小 [Description(" 每页记录数 " ),Bindable( true ),Category( " Appearance " ),DefaultValue( 10 )] public int PageSize { get { return _iPageSize; } set { if (value == 0 ) { _iPageSize = 10 ; } else { _iPageSize = 10 ; } } } #endregion 页规格 #region 页规格 [Description(" 一次显示多少页 " ),Bindable( true ),Category( " Appearance " ),DefaultValue( 10 )] public int ItemSize { get { return _iItemSize; } set { if (value <= 0 ) { _iItemSize = 10 ; } else { _iItemSize = value; } } } #endregion 当前页码 #region 当前页码 [Description(" 当前选择页码 " ),Bindable( true ),Category( " Appearance " ),DefaultValue( 1 )] public int CurrentPage { get { return _iCurrentPage; } set { if (value <= 0 ) { _iCurrentPage = 1 ; } else { _iCurrentPage = value; } } } #endregion 总页数 #region 总页数 [ Description(" 总的页数 " ), Bindable( true ), Category( " Appearance " ), DefaultValue( 0 ) ] public int TotalPage { get { return _iTotalPage; } } #endregion 页码颜色 #region 页码颜色 [ Description(" 页码颜色 " ), Bindable( true ), Category( " Appearance " ), DefaultValue( " Navy " ) ] private string LinkColor { get { return _strLinkColor; } set { _strLinkColor = value; } } #endregion 当前选择页码颜色 #region 当前选择页码颜色 [ Description(" 当前选择页码颜色 " ), Bindable( true ), Category( " Appearance " ), DefaultValue( " #EEEEEE " ) ] private string CurrentPageColor { get { return _strCurrColor; } set { _strCurrColor = value; } } #endregion 当前控件样式表 #region 当前控件样式表 [ Description(" 当前控件样式表 " ), Bindable( true ), Category( " Appearance " ), DefaultValue( " none " ) ] private string ControlCssClass { get { return _strCssClass; } set { _strCssClass = value; } } #endregion 上一页图片 #region 上一页图片 [ Description(" 上一页图片 " ), Bindable( true ), Category( " Appearance " ), DefaultValue( "" ) ] public string PrevICON { get { return _strPrevICON; } set { _strPrevICON = value; } } #endregion 下一页图片 #region 下一页图片 [ Description(" 下一页图片 " ), Bindable( true ), Category( " Appearance " ), DefaultValue( "" ) ] public string NextICON { get { return _strNextICON; } set { _strNextICON = value; } } #endregion 上一页按钮的文字 #region 上一页按钮的文字 [ Description(" 上一页按钮文字 " ), Bindable( true ), Category( " Appearance " ), DefaultValue( " 上一页 " ) ] public string PrevTitle { get { return _strPrevTitle; } set { _strPrevTitle = value; } } #endregion 下一页按钮的文字 #region 下一页按钮的文字 [ Description(" 下一页按钮文字 " ), Bindable( true ), Category( " Appearance " ), DefaultValue( " 下一页 " )] public string NextTitle { get { return _strNextTitle; } set { _strNextTitle = value; } } #endregion 上一页的提示信息 #region 上一页的提示信息 [ Description(" 上一页鼠标放上显示信息 " ), Bindable( true ), Category( " Appearance " ), DefaultValue( "" ) ] public string PrevMessage { get { return _strPrevMessage; } set { _strPrevMessage = value; } } #endregion 下一页的提示信息 #region 下一页的提示信息 [ Description(" 下一页鼠标放上显示信息 " ), Bindable( true ), Category( " Appearance " ), DefaultValue( "" ) ] public string NextMessage { get { return _strNextMessage; } set { _strNextMessage = value; } } #endregion 数字导航提示信息 #region 数字导航提示信息 [ Description(" 数字导般鼠标放上显示信息 " ), Bindable( true ), Category( " Appearance " ), DefaultValue( "" ) ] public string PageNOMessage { get { return _strPageNOMessage; } set { _strPageNOMessage = value; } } #endregion 分页控件按钮类型 #region 分页控件按钮类型 [ Description(" 分页控件按钮类型 " ), Bindable( true ), Category( " Appearance " ), DefaultValue( 0 ) ] public PageButtonStyle ButtonStyle { get { return pageButtonStyel; } set { pageButtonStyel = value; } } #endregion #endregion 定义事件 #region 定义事件 /**/ /// <summary> /// 定义选择页委托 /// </summary> /// <param name="sender"> 事件对象 </param> /// <param name="e"> 事件参数 </param> /// 作者:不懂 /// 日期:2006-11-8 public delegate void PageChangeEventHandler( object sender, EventArgs e); /**/ /// <summary> /// 定义事件 /// </summary> /// 作者:不懂 /// 日期:2006-11-8 public event PageChangeEventHandler ChangePageClick; #endregion 构造涵数 #region 构造涵数 public PageList() : base (HtmlTextWriterTag.Div) { } #endregion 重写的方法 #region 重写的方法 /**/ /// <summary> /// 定义当前控件的DIV样式 /// </summary> /// <param name="writer"></param> /// 作者:不懂 /// 日期:2006-11-8 protected override void AddAttributesToRender(HtmlTextWriter writer) { writer.AddStyleAttribute( " White-space " , " nowrap " ); writer.AddStyleAttribute( " Padding-Top " , " 2px " ); writer.AddStyleAttribute( " Padding-Bottom " , " 2px " ); writer.AddStyleAttribute( " Width " , Width.ToString()); writer.AddStyleAttribute( " Height " , Height.ToString()); base .AddAttributesToRender(writer); } /**/ /// <summary> /// 客户端回发处理事件 /// </summary> /// <param name="eventArgument"></param> /// 作者:不懂 /// 日期:2006-11-8 public void RaisePostBackEvent( string eventArgument) { int PageIndex = int .Parse(eventArgument); this ._iCurrentPage = PageIndex; OnPageChangeClick( new EventArgs()); } /**/ /// <summary> /// 响应页码选择的事件方法 /// </summary> /// <param name="e"></param> /// 作者:不懂 /// 日期:2006-11-8 protected virtual void OnPageChangeClick(EventArgs e) { if (ChangePageClick != null ) { ChangePageClick( this , e); } } /**/ /// <summary> /// 为控件的呈现指定输出参数 /// </summary> /// <param name="writer"></param> /// 作者:不懂 /// 日期:2006-11-8 public override void RenderControl(HtmlTextWriter writer) { if (TotalRecord > 0 ) { PageCurAndTotal(writer); PageBegin(writer); PageItemList(writer); } base .RenderControl(writer); } #endregion 私有方法 #region 私有方法 /**/ /// <summary> /// 输出"当前页/总页数" /// </summary> /// <param name="output"></param> /// 作者:不懂 /// 日期:2006-11-8 private void PageCurAndTotal(HtmlTextWriter output) { this ._iTotalPage = ( this .TotalRecord % this .PageSize) == 0 ? ( this .TotalRecord / this .PageSize) : ( this .TotalRecord / this .PageSize) + 1 ; output.Write(CurrentPage.ToString() + " / " + TotalPage.ToString()); } private void PageBegin(HtmlTextWriter output) { string strBegin = string .Empty; string strPrev; if ( this .ButtonStyle == PageButtonStyle.Text) { strPrev = this .PrevTitle; } else { strPrev = " <img src=' " + this .PrevICON + " ' alt=' " + this .PrevMessage + " '/> " ; } if (CurrentPage > 1 ) strBegin = " <a id=\ "" + this.UniqueID + " \ " title=' " + this .PrevMessage + " ' href=\ " javascript: " + Page.GetPostBackEventReference(this, (CurrentPage - 1).ToString()) + " \ " > " + strPrev + " </a> " ; output.Write(strBegin); } private void PageItemList(HtmlTextWriter output) { string strPageIndexColor = string .Empty; string strPageItemList = string .Empty; int MaxItem = this .ItemSize / 2 + (CurrentPage - 1 ) > TotalPage ? TotalPage : this .ItemSize / 2 + (CurrentPage - 1 ); int MinItem = MaxItem <= this .ItemSize ? 1 : (MaxItem - ItemSize) + 1 ; for ( int item = MinItem; item <= MaxItem; item ++ ) { strPageIndexColor = item == CurrentPage ? this .CurrentPageColor : this .LinkColor; if (item == CurrentPage) { strPageItemList += " <font color=' " + strPageIndexColor + " '> " + item.ToString() + " </font> " ; } else { strPageItemList += " <a id=\ "" +this.UniqueID+ " \ " title=' " + PageNOMessage + item.ToString() + " 页 ' href=\ " javascript: " +Page.GetPostBackEventReference(this,item.ToString())+ " \ " <font color= " + strPageIndexColor + " > " + item.ToString() + " </font></a> " ; } } output.Write(strPageItemList); // 输出尾部 string strEnd = string .Empty; string strNext; if ( this .ButtonStyle == PageButtonStyle.Text) { strNext = this .NextTitle; } else { strNext = " <img src=' " + this .NextICON + " ' alt=' " + this .NextMessage + " '/> " ; } if (TotalPage > 1 && MaxItem < TotalPage) strEnd = " <a id=\ "" + this.UniqueID + " \ " title=' " + this .NextMessage + " ' href=\ " javascript: " + Page.GetPostBackEventReference(this, (CurrentPage + 1).ToString()) + " \ " > " + strNext + " </a> " ; output.Write(strEnd); } #endregion } }