呵呵!今天午觉没睡好,感觉太热了,睡了一下子就热醒了,同事们都不吹空调了,没办法!
现在已经是上班时间了,但一点也不想做事,再加上没睡好,头晕晕的,跑到洗手间用冷水洗
一把脸,回到办公桌前,就想到先写篇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
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

}
}
现在已经是上班时间了,但一点也不想做事,再加上没睡好,头晕晕的,跑到洗手间用冷水洗
一把脸,回到办公桌前,就想到先写篇BLOG吧,昨天写了一个分页控件,把它写到自己的BLOG
上去,呵呵!其实这个控件之前是我同事写的,昨天闲得无聊,就想到把同事那个控件改进一下
吧,我觉得搞得太复杂了(按钮太多、、、,我自认为不需要那些东东)
我同事把这个控件称之为“无源虚拟分页控件”因为它是不需要数据源的,只起到虚拟选择页
号与定位的作用,只需要指定其 TotalRecord(记录总数)就可以帮你虚拟分页了.
控件的按钮支持文字和图片俩种格式,可以设定其版页最大显示数,每页显示记录数,以及鼠标
放在按钮上的提示信息.
由于是无源虚拟分页,所以控件必须给定 TotalRecord(记录总数)以及实现ChangePageClick事件
那么记录的总数怎么出来呢,那当然是通过存储过程来取得了,这个存储过程必须是每次取得的数据
是当前展示所需要的(也就是说取当前页的记录),如果一股脑儿把所有满足条件的数据全取出来
那根本就没有意义了,所以呢,要实现分页这个存储过程也是很重要的。
下面是我做DEMO的存储过程








































这个分页控件是个完全自定义的控件没有UI的,继承于WebControl,为了响应事件还得继承IPostBackEventHandler,下面就是完整的实现代码。































































































































































































































































































































































































































































































































































































































































































http://www.cnblogs.com/sunming0905/archive/2006/11/09/555362.html