继SqlPager之后推出一款可用于前台页面的分页控件--UrlPager

      使用方法其实和SqlPager一样,用的存储过程也是同一个,只是SqlPager更是个用于后台管理和B/S应用系统中,因为他是采用的Postback实现的翻页;而今天推出的Urlpager是使用的通过在Url地址中传递参数(page=1...)实现的。闲话不多说了,转入正题。(使用环境:WindowsServer2003(IIS6.0)+.Net Framework2.0+MSSQL2000.

使用的分页存储过程:
CREATE PROC [dbo].[sp_PageView]
@tbname     varchar(4000),      --要分页显示的表名
@FieldKey   nvarchar(1000),      --用于定位记录的主键(惟一键)字段,可以是逗号分隔的多个字段
@PageCurrent int=1,               --要显示的页码
@PageSize   int=10,                --每页的大小(记录数)
@FieldShow nvarchar(1000)='',      --以逗号分隔的要显示的字段列表,如果不指定,则显示所有字段
@FieldOrder nvarchar(1000)='',  --以逗号分隔的排序字段列表,可以指定在字段后面指定DESC/ASC    用于指定排序顺序
@Where    nvarchar(1000)=''     --查询条件
--
@PageCount int OUTPUT         --总页数
AS
SET NOCOUNT ON
--检查对象是否有效
--
IF OBJECT_ID(@tbname) IS NULL
--
BEGIN
--
RAISERROR(N'对象"%s"不存在',1,16,@tbname)
--
    RETURN
--
END
IF OBJECTPROPERTY(OBJECT_ID(@tbname),N'IsTable')=0
    
AND OBJECTPROPERTY(OBJECT_ID(@tbname),N'IsView')=0
    
AND OBJECTPROPERTY(OBJECT_ID(@tbname),N'IsTableFunction')=0
BEGIN
    
RAISERROR(N'"%s"不是表、视图或者表值函数',1,16,@tbname)
    
RETURN
END

--分页字段检查
IF ISNULL(@FieldKey,N'')=''
BEGIN
    
RAISERROR(N'分页处理需要主键(或者惟一键)',1,16)
    
RETURN
END

--其他参数检查及规范
IF ISNULL(@PageCurrent,0)<1 SET @PageCurrent=1
IF ISNULL(@PageSize,0)<1 SET @PageSize=10
IF ISNULL(@FieldShow,N'')=N'' SET @FieldShow=N'*'
IF ISNULL(@FieldOrder,N'')=N''
    
SET @FieldOrder=N''
ELSE
    
SET @FieldOrder=N'ORDER BY '+LTRIM(@FieldOrder)
IF ISNULL(@Where,N'')=N''
    
SET @Where=N''
ELSE
    
SET @Where=N'WHERE ('+@Where+N')'

--如果@PageCount为NULL值,则计算总页数(这样设计可以只在第一次计算总页数,以后调用时,把总页数传回给存储过程,避免再次计算总页数,对于不想计算总页数的处理而言,可以给@PageCount赋值)
--
IF @PageCount IS NULL
--
BEGIN
--
    DECLARE @sql nvarchar(4000)
--
    SET @sql=N'SELECT @PageCount=COUNT(*)'
--
        +N' FROM '+@tbname
--
        +N' '+@Where
--
    EXEC sp_executesql @sql,N'@PageCount int OUTPUT',@PageCount OUTPUT
--
    SET @PageCount=(@PageCount+@PageSize-1)/@PageSize
--
END

--计算分页显示的TOPN值
DECLARE @TopN varchar(20),@TopN1 varchar(20)
SELECT @TopN=@PageSize,
    
@TopN1=(@PageCurrent-1)*@PageSize

--第一页直接显示
IF @PageCurrent=1
    
EXEC(N'SELECT TOP '+@TopN
        
+N' '+@FieldShow
        
+N' FROM '+@tbname
        
+N' as xx '+@Where
        
+N' '+@FieldOrder)
ELSE
BEGIN
    
--处理别名
    IF @FieldShow=N'*'
        
SET @FieldShow=N' tempPage.*'

    
--生成主键(惟一键)处理条件
    DECLARE @Where1 nvarchar(4000),@Where2 nvarchar(4000),
        
@s nvarchar(1000),@Field sysname
    
SELECT @Where1=N'',@Where2=N'',@s=@FieldKey
    
WHILE CHARINDEX(N',',@s)>0
        
SELECT @Field=LEFT(@s,CHARINDEX(N',',@s)-1),
            
@s=STUFF(@s,1,CHARINDEX(N',',@s),N''),
            
@Where1=@Where1+N' AND tempPage.'+@Field+N'=tempPageb.'+@Field,
            
@Where2=@Where2+N' AND tempPageb.'+@Field+N' IS NULL',
            
@Where=REPLACE(@Where,@Field,N'tempPage.'+@Field),
            
@FieldOrder=REPLACE(@FieldOrder,@Field,N'tempPage.'+@Field),
            
@FieldShow=REPLACE(@FieldShow,@Field,N'tempPage.'+@Field)
    
SELECT @Where=REPLACE(@Where,@s,N'tempPage.'+@s),
        
@FieldOrder=REPLACE(@FieldOrder,@s,N'tempPage.'+@s),
        
@FieldShow=REPLACE(@FieldShow,@s,N'tempPage.'+@s),
        
@Where1=STUFF(@Where1+N' AND tempPage.'+@s+N'=tempPageb.'+@s,1,5,N''),    
        
@Where2=CASE
            
WHEN @Where='' THEN N'WHERE ('
            
ELSE @Where+N' AND ('
            
END+N'tempPageb.'+@s+N' IS NULL'+@Where2+N')'

    
--执行查询
    EXEC(N'SELECT TOP '+@TopN
        
+N' '+@FieldShow
        
+N' FROM '+@tbname
        
+N' tempPage LEFT JOIN(SELECT TOP '+@TopN1
        
+N' '+@FieldKey
        
+N' FROM '+@tbname
        
+N' tempPage '+@Where
        
+N' '+@FieldOrder
        
+N')tempPageb ON '+@Where1
        
+N' '+@Where2
        
+N' '+@FieldOrder)
END
GO
 
(注:这个分页存储过程是借鉴的一位同行的,具体哪位已经记不清楚了)
 
使用方法:
///<summary>
    
/// 绑定UrlPager数据 存储过程的分页
    
/// </summary>
    
/// <param name="sqlPager">UrlPager控件ID</param>
    
/// <param name="sort">排序方式</param>
    
/// <param name="sortfied">排序字段</param>
    
/// <param name="FieldKey">关键字段(主键)</param>
    
/// <param name="ConnectString">数据库链接字符串</param>
    
/// <param name="ControlName">绑定的网格控件</param>
    
/// <param name="CommandText">SQL语句</param>
    
/// <param name="TableName">数据表表名(可以是复杂的查询)</param>
    
/// <param name="Fields">查询字段</param>
    
/// <param name="SqlCondition">Where条件</param>
    public void BindSqlPager(UrlPagerControl.UrlPager urlPager, UrlPager.SortMode sort,
        
string sortfied, string FieldKey, string ConnectString, string ControlName, string CommandText,
        
string TableName, string Fields, string SqlCondition)
    {
        urlPager.ConnectionString 
= ConnectString;
        urlPager.ControlToPaginate 
= ControlName;
        urlPager.SelectCommand 
= CommandText;
        urlPager.SortMode 
= sort;
        urlPager.FieldKey 
= FieldKey;
        urlPager.SortField 
= sortfied;
        urlPager.TableName 
= TableName;
        urlPager.Fields 
= Fields;
        urlPager.SQLCondition 
= SqlCondition;
        urlPager.DataBind();

    }

调用方法:
this.BindSqlPager(this.UrlPager1, sortmode, sortfield, "ID"this.GetDbConnectString(), "DataList1"this.CommandSQL, "(" + this.CommandSQL + ")""*""ID>0");


其中CommandSQL为你自己的复杂的查询语句,比如select a.
*,b.* from A as a left join B as b where a.id=b.id 

 

 

控件的关键代码:
      
/**//// <summary>
       
/// 呈现
        
/// </summary>
        
/// <param name="writer"></param>
        protected override void Render(HtmlTextWriter writer)
        {            
            
string curPage = "";
            
string query = "";
            
if (Context != null)
            {
                query 
= Page.Request.Url.Query.Replace('?''&');
            }
            curPage 
= query == "" ? "&page=1" : query;
            query 
= RX.Replace(query, String.Empty, -1);
            query 
= "<a href='?page={0}" + query + "'>{1}</a>&nbsp;";

            
// Prepare the necessary number
            int page = CurrentPage;
            
int count = PageCount;
            
int nums = NumberCount - 1;
            
int center = nums / 2;
            
int beginIndex = 1;

            
// Calculate the first page number in the pagger bar
            if (count > nums && page > center)
            {
                beginIndex 
= page - center;
                
if ((count - beginIndex) <= nums)
                    beginIndex 
= count - nums;
            }

            
// Calculate the last page number in the pagger bar
            int endIndex = beginIndex + nums;
            
if (endIndex > count)
                endIndex 
= count;

            
// Render the pagger bar

            writer.AddAttribute(HtmlTextWriterAttribute.Id, ClientID);
            
if (!String.IsNullOrEmpty(_class))
            {
                writer.AddAttribute(HtmlTextWriterAttribute.Class, _class);
            }
            
else
            {
                
            }
            writer.RenderBeginTag(HtmlTextWriterTag.Div);

            
            writer.Write(String.Format(query, page 
> 1 ? (page - 1) : 1, PrevText));
            writer.Write(String.Format(query, 
1"1")+FirstText);

            
for (int i = beginIndex; i <= endIndex; i++)
            {
                
if (page == i)
                {
                    
string _tempUrl = query.Replace("'>""' class='" + this.VisitedCss + "'>");
                    writer.Write(String.Format(_tempUrl, i, i));
                     }
                
else
                {
                                            writer.Write(String.Format(query, i, i));
                }
            }
            writer.Write(LastText 
+ String.Format(query, count, count.ToString()));
            writer.Write(String.Format(query, page 
< count ? (page + 1) : page, NextText));
            
            

            writer.RenderEndTag();
        }        

        
/**//// <summary>
        
/// 重载数据绑定   取得,填充数据
        
/// </summary>
        public override void DataBind()
        {
            
//this.SelectCommand=string.Format("exec sp_PageView '{0}','{1}','{2}',{3},{4},{5},{6},'{7}'",this.TableName,this.Fields,this.SortField,this.ItemsPerPage,(this.CurrentPageIndex+1),0,(this.SortMode==LJHSqlPager2.SortMode.DESC?"1":"0"),this.SQLCondition);

            
object[] param ={
                               
this.TableName,
                               
this.FieldKey,
                               
this.CurrentPage,
                               
this.PageSize,
                               
this.Fields,
                               
this.SortField+(this.SortMode==SortMode.DESC?" DESC":" ASC"),
                               
this.SQLCondition
                           };
            
this.SelectCommand = string.Format("exec sp_PageView '{0}','{1}',{2},{3},'{4}','{5}','{6}'", param);

            
// 触发数据绑定事件
            base.DataBind();

            
// 控件必须在数据绑定后重新创建
            ChildControlsCreated = false;

            
// 确定数据容器存在并且为列表控件(list control)
            if (ControlToPaginate == "")
                
return;
            _controlToPaginate 
= Page.FindControl(ControlToPaginate);
            
if (_controlToPaginate == null)
                
return;
            
if (!(_controlToPaginate is BaseDataList
                
|| _controlToPaginate is ListControl
                
|| _controlToPaginate is CompositeDataBoundControl
                
|| _controlToPaginate is Repeater))
                
return;

            
// 确定数据库连接字符串有效且查询命令已指定
            if (ConnectionString == "" || SelectCommand == "")
                
return;

            
// 取得数据
            
//if (PagingMode == PagingMode.Cached)
            
//FetchAllData();
            
//else
            
//{
            
//    //if (SortField == "")
            
//    //    return;
            FetchPageData();
            
//}


            
// Bind data to the buddy control
            
// 绑定数据到数据容器

            BaseDataList baseDataListControl 
= null;
            ListControl listControl 
= null;
            
if (_controlToPaginate is BaseDataList)
            {
                baseDataListControl 
= (BaseDataList)_controlToPaginate;
                baseDataListControl.DataSource 
= _dataSource;
                baseDataListControl.DataBind();
                
return;
            }
            
if (_controlToPaginate is ListControl)
            {
                listControl 
= (ListControl)_controlToPaginate;
                listControl.Items.Clear();
                listControl.DataSource 
= _dataSource;
                listControl.DataBind();
                
return;
            }
            
if (_controlToPaginate is CompositeDataBoundControl)
            {
                GridView gv 
= (GridView)_controlToPaginate;
                gv.DataSource 
= _dataSource;
                gv.DataBind();
                
return;
            }
            
if (_controlToPaginate is Repeater)
            {
                Repeater rep 
= (Repeater)_controlToPaginate;
                rep.DataSource 
= _dataSource;
                rep.DataBind();
                
return;
            }
        }
主要的核心代码就是呈现数据和绑定数据,大家一看代码就知道了,我也不用多说,不过要提醒的一点是显示的页面是可以自己设置的。
效果图片:
源码下载:UrlPager
 如有问题可留言,我会抽时间答复!谢谢大家支持。
posted @ 2008-08-10 00:34  Hermes.Liu  阅读(1082)  评论(2编辑  收藏  举报