继昨晚用存储过程实现之后,以前一直打算着写个自己定义的分页按钮终于在今晚动手了,这样是为了结合分页查询实现的,以前都是使用别人的分页插件,现在自己写个,成就感也是蛮大的,嘿嘿!
(1)先定义好分页按钮样式,我在Dreamweaver先写好分页按钮样式,这样就可以方便地根据自己的要求来定义,也利于修改。
<style type='text/css'>
body
{
font-family: '微软雅黑';
padding:0;
margin:0;
}
.pagerDiv ul
{
padding:0;
margin:0;
}
.pagerDiv ul li
{
display:inline-block;
text-align:center;
line-height: 24px;
cursor:pointer;
background-color:#f33;
color:#fff;
min-width:34px;
height:24px;
margin-right:5px;
}
.pagerDiv a, .pagerDiv a:visited
{
display:block;
background-color:#f96;
text-decoration: none;
color:#fff;
min-width:34px;
height:24px;
text-align:center;
line-height: 24px;
}
.pagerDiv a:hover
{
display: block;
background-color:#f33;
color:#fff;
text-decoration: none;
min-width:34px;
height:24px;
text-align:center;
line-height: 24px;
}
</style>
HTML代码:
<span style="white-space:pre"> </span><div>
<%=TableStr %>
</div>
<div>
<%=PagingStr %>
</div>
(2)先实现一个简单版本的
刚开始写的时候,没有考虑那么多的需求变化,只是简单地根据分页的数目直接生成,即,查询后分页总数一共为19页,那么就全部显示在网页上。这个是比较好实现的,十几分钟就写完了。
(3)麻烦的来了,产品经理过来,我保证不打死你!!
需求总是变化的,不可能直接分页有多少就直接往网页上放,这个可以根据需求来设定的,这样的话,就会产生比较多的分页边界考虑了。
1、设FootPageSize = 网页显示分页的个数
PageSize = 一个分页显示的数据记录数量
TotalCount = 所有的数据记录总数
2、结合两者来看,一个分页显示的数据记录数量是比较容易实现的,毫无问题,但麻烦的就是FootPageSize了,因为限制了网页上显示分页的个数,那么就需要将分页进行分区间,比如:
ToTalCount = 20, PageSize = 4, FootPageSize = 3;
那么 一个页面显示4条记录, 共需 20/4 =5 个分页, 而 分页区间 共需要 5/3 = 1.666666,向上取整变成2个区段: 第1区间 : 1,2,3 第2区间 : 4,5。
因为我自己定义的分页样式为 “ 首页,上一页,.....(这里表示去到上一个区间),2,3,4,.....(这里点击表示去到下一个区间),下一页,尾页”这样的形式。于是麻烦就不断地来了。
这个思考过程进行到最后有点混乱,请允许我跳过这一段吧!: )
最后,经过不断地调试与思考边界,写出了如下的代码,确实有点混乱,也加入了太多的判断,后面找个日子再整理一下思路写个好看点的!~
public string TableStr; //数据显示
public string PagingStr; //页脚显示
private int PageSize = 4; //每页显示数据条目
private int FootPageSize = 10; //页脚显示条目
DataTable dt = null;
private SqlConnection SCON = null;
private string ConnectStr = "SERVER=localhost;DATABASE=TCJOB;UID=dpan;PWD=dpan";
protected void Page_Load( object sender, EventArgs e )
{
if( !IsPostBack )
{
string PageIndex = Request.QueryString["PageIndex"] as string;
if( !string.IsNullOrEmpty( PageIndex ) ) //跳到某一页
{
GetData( Convert.ToInt32( PageIndex ) );
}
else
{
//首页加载的话
GetData( 1 );
}
}
}
/// <summary>
/// 获取数据
/// </summary>
/// <param name="PageIndex"></param>
protected void GetData( int PageIndex )
{
dt = ExcuteProcedure( PageSize, PageIndex );
TableStr = TransDTtoTable( ref dt ); //生成数据字符串
PagingStr = ProductPager( PageIndex ); //生成分页
}
/// <summary>
/// 生成分页字符串
/// </summary>
/// <param name="PageIndex"></param>
/// <returns></returns>
protected string ProductPager( int PageIndex )
{
StringBuilder Pager = new StringBuilder();
int ToTalCount = GetTotalRowsNum();
int NeedPage = ToTalCount / PageSize + ( ToTalCount % PageSize > 0 ? 1 : 0 ); //计算显示数据所需要的页数
int SectionNum = NeedPage / FootPageSize + ( NeedPage % FootPageSize > 0 ? 1 : 0 ); //总共显示分页所需要的区段数目
//将分页分区段显示,需要判断PageIndex的区间范围
int PosSection = ( PageIndex / FootPageSize ); //所在的区段下标
int LowerBound = PosSection * FootPageSize; //下标*单位区段显示分页数 = 分页下标起点
int UpperBound = LowerBound + FootPageSize; //分页下标终点
LowerBound = LowerBound == 0 ? 1 : LowerBound; //防止越界
UpperBound = UpperBound > NeedPage ? NeedPage : UpperBound; //防止越界
Pager.Append( "<div class='pagerDiv'><ul>" );
for( int i = LowerBound; i <= UpperBound; i++ )
{
if( LowerBound == i ) //分页第一页
{
if( LowerBound == PageIndex )
{
if( PosSection > 0 )
{
Pager.Append( "<li><a href='TestPage.aspx?PageIndex=1'>首页</a></li><li><a href='TestPage.aspx?PageIndex=" + ( LowerBound - 1 ).ToString() + "'>上一页</a></li>" );
Pager.Append( "<li><a href='TestPage.aspx?PageIndex=" + ( LowerBound - 1 ).ToString() + "'>...</a></li>" );
}
else
{
Pager.Append( "<li><a>首页</a></li><li><a>上一页</a></li>" );
}
Pager.Append( "<li>" + LowerBound.ToString() + "</li>" );
}
else
{
Pager.Append( "<li><a href='TestPage.aspx?PageIndex=1'>首页</a></li>" );
Pager.Append( "<li><a href='TestPage.aspx?PageIndex=" + (PageIndex-1).ToString() + "'>上一页</a></li>" );
if( PosSection > 0 )
{
Pager.Append( "<li><a href='TestPage.aspx?PageIndex=" + ( LowerBound - 1 ).ToString() + "'>...</a></li>" );
}
Pager.Append( "<li><a href='TestPage.aspx?PageIndex="+LowerBound.ToString()+"'>"+LowerBound.ToString()+"</a></li>" );
}
continue;
}
if( UpperBound == i ) //分页最后一页
{
if( UpperBound == PageIndex ) //如果点击到的是最后一页,则“下一页”跟“尾页”按钮都失效
{
Pager.Append( "<li>" + i.ToString() + "</li><li><a>下一页</a></li>" );
Pager.Append( "<li><a>尾页</a></li>" );
}
else
{
Pager.Append( "<li><a href='TestPage.aspx?PageIndex=" + i.ToString() + "'>" + i.ToString() + "</a></li>" );
if( PosSection < SectionNum - 1 )
{
Pager.Append( "<li><a href='TestPage.aspx?PageIndex=" + ( UpperBound+1 ).ToString() + "'>...</a></li>" );
}
Pager.Append( "<li><a href='TestPage.aspx?PageIndex=" + (PageIndex+1).ToString() + "'>下一页</a></li>" );
Pager.Append( "<li><a href='TestPage.aspx?PageIndex=" + NeedPage.ToString() + "'>尾页</a></li>" );
}
break;
}
if( i == PageIndex )
{
Pager.Append( "<li>" + i.ToString() + "</li>" );
}
else
{
Pager.Append( "<li><a href='TestPage.aspx?PageIndex=" + i.ToString() + "'>" + i.ToString() + "</a></li>" );
}
}
Pager.Append( "</ul></div>" );
return Pager.ToString();
}
/// <summary>
/// 获取所有的记录总数
/// </summary>
/// <returns></returns>
protected int GetTotalRowsNum()
{
OpenDataBase();
string SQL = "SELECT COUNT(*) FROM Article WITH(NOLOCK) ";
SqlCommand SCOM = new SqlCommand( SQL, SCON );
int result = Convert.ToInt32( SCOM.ExecuteScalar().ToString() );
CloseDataBase();
return result;
}
/// <summary>
/// 转换成HTML Table字符串
/// </summary>
/// <param name="dt"></param>
/// <returns></returns>
protected string TransDTtoTable( ref DataTable dt )
{
StringBuilder sb = new StringBuilder();
sb.Append( "<table>" );
for( int i = 0; i < dt.Rows.Count; i++ ) //读取每一行
{
sb.Append( "<tr>" );
for( int j = 0; j < dt.Columns.Count; j++ ) //读取每一列
{
sb.Append( "<td>" + dt.Rows[i][j].ToString() + "</td>" );
}
sb.Append( "</tr>" );
}
sb.Append( "</table>" );
return sb.ToString();
}
/// <summary>
/// 打开数据库链接
/// </summary>
protected void OpenDataBase()
{
if( null == SCON )
{
SCON = new SqlConnection( ConnectStr );
SCON.Open();
}
}
/// <summary>
/// 关闭数据库链接
/// </summary>
protected void CloseDataBase()
{
if( null != SCON )
{
SCON.Close();
SCON = null;
}
}
/// <summary>
/// 执行SQL存储过程
/// </summary>
/// <param name="PageSize"></param>
/// <param name="PageIndex"></param>
/// <returns></returns>
protected DataTable ExcuteProcedure( int PageSize, int PageIndex )
{
OpenDataBase(); //打开与数据库的链接
string SQL = "SELECT COUNT(*) FROM Article WITH(NOLOCK) ";
SqlCommand SCOM = new SqlCommand( SQL, SCON );
SCOM.CommandText = "paging"; //存储过程名称
SCOM.CommandType = CommandType.StoredProcedure; //执行命令类型为存储过程
SqlParameter [] Paras = new SqlParameter[]{ new SqlParameter("@PageSize", SqlDbType.Int), new SqlParameter("@PageIndex",SqlDbType.Int) };
Paras[0].Value = PageSize;
Paras[1].Value = PageIndex;
SCOM.Parameters.Clear(); //清空参数
foreach( SqlParameter items in Paras ) //填充参数
{
SCOM.Parameters.Add( items );
}
SqlDataAdapter sdr = new SqlDataAdapter( SCOM ); //获取读取适配器,当然也可以使用SqlDataReader
DataSet ds = new DataSet();
sdr.Fill( ds );
CloseDataBase(); //别忘记了关闭数据库的链接
return ds.Tables[0];
}
经过一些测试,目前运行还算可以,虽然还有一点小BUG,另外还有一个比较严重的问题(其实也不算是严重),当FootPageSize == 1的时候,生成的分页根本就不完整,导致无法使用。(当然,设想下,谁会无聊到设置一个页面只显示一个分页???!)
来几张图片展示下:
好了,就是这样了,晚安,亲们~