ASP.NET页面自定义列表和分页

ASP.NET页面自定义列表和分页_第1张图片  

     这个例子展示如何使用SQL Server 2005 的ROW_NUMBER功能去分页,以及通过在code-behind中自定义HTML输出比较好看的界面。

   首先,我们必须去选择的列表记录,通常使用的分页技术是我们将所有的记录放入一个dataset,然后使用PagedDataSource来显示适当的页。这种技术主要不好的地方是在内存中存储了所有的记录,而在页面上仅仅显示其中的一些记录。每次你点击页码,每次它都将查询了所有的记录。为了克服这个头痛的问题,我将有效地使用SQL Server 2005的ROW_NUMBER 功能。

    我们将传递两个参数,存储过程能查询特定的记录。

    @intCurrentPage int - 这个参数用来表示当前页码。

    @intRecordPerPage int -  这个参数用来得到一页中显示的记录数量。

    例如,如果我们将 @intCurrentPage设置为1 ,将@intRecordPerPage设置为10,结果将会是1到10的记录。 这个存储过程连接到AdventureWorks数据库,从Production.Product 查询记录。

代码
SET  ANSI_NULLS  ON
GO
SET  QUOTED_IDENTIFIER  ON
GO
--  =============================================
--
 Author: 
--  Create date: 24-12-2009
--
 Description: To get specific records from product table 
--
       of AdventureWorks database.
--
 =============================================
set  ANSI_NULLS  ON
set  QUOTED_IDENTIFIER  ON
go

CREATE   PROCEDURE   [ dbo ] . [ uspFetchProduct ]
@intCurrentPage   int ,
@intRecordPerPage   int
AS
BEGIN
    
SET  NOCOUNT  ON ;

    
-- ***Find the starting record id and ending record id ****
     declare   @intStartRec   int
    
set   @intStartRec = ( @intCurrentPage * @intRecordPerPage ) - @intRecordPerPage
    
declare   @intEndRec   int
    
set   @intEndRec = ( @intCurrentPage * @intRecordPerPage ) + 1     
    
-- ********************************************************

    
Begin
        
-- ***Select the records from @intStartRec to @intEndRec ***
         Select   *   from
        (
            
select  ROW_NUMBER()  OVER  ( ORDER   BY  ProductID)  as  SlNo,ProductID,
            
[ Name ] ,ProductNumber,StandardCost
             from  Production.Product
        ) 
Temp
        
Where  SlNo > @intStartRec   and  SlNo < @intEndRec     
        
-- ***********************************************************

        
-- ***Get the total number of records***************
         select   COUNT (ProductID)  as  TotalRecords
        
from  Production.Product
        
-- ************************************************
     End
END

     通过传递:@intCurrentPage=1, @intRecordPerPage=10,执行上面的存储过程

ASP.NET页面自定义列表和分页_第2张图片   

    第一个结果集是第一页的记录,第二个结果集是记录的总和。

    在AdventureWorks 数据库中执行这个存储过程,创建一个连接字符串来连接AdventureWorks。

connectionString  = "Data Source = [ SERVER NAME ] ;
   Initial Catalog
= AdventureWorks; User  ID = [ USERNAME ] ; Password = [ PASSWORD ] />

    现在我们在数据库中准备好存储过程,开始实现我们的列表和分页方法。 为了显示列表,我将不使用任何数据源控件,我将直接在aspx页面上输出。对于这个,在后台代码中,我们首先定义两个字符串。

    protected   string  strList;  //  to set the HTML of the listing
    protected   string  strPages; // to set the HTML of paging

     字符串变量strList 用来保存记录的列表的HTML,strPages 用来保存分页的HTML。首先,我必须得到页的索引,我将页的索引存放在隐藏的文本字段中(txtHidPageIndex)。默认,第一页将被显示。我们将用户点击的页索引,将它存储在这个隐藏字段中 ,服务端能访问这个隐藏字段来获得页码。我们需要一个服务端控件来监听页面的点击。 我在页面上添加一个link button控件(lnkPaging)来初始化clicking,它也能完成一些服务端的动作。

    写一个javascript函数来接受页码和将页码以及将它放到隐藏字段中。 在此之后,执行link button的回传,这样我们能执行服务端的操作。该链接按钮的Click事件可以发起的ASP.NET doPostBack方法。

function  doPaging(intPageIndex)
{
    document.getElementById(
' txtHidPageIndex ' ).value = intPageIndex;
    __doPostBack(
' lnkPaging ' , '' );
}

  link button (lnkPaging) 的后台代码如下:

      protected   void  lnkPaging_Click( object  sender, EventArgs e)
        {
            DoSearch(
int .Parse(txtHidPageIndex.Value));
        }

     下面的片段显示如何将记录填充到reader中。

代码
   private   void  DoSearch( int  intPageIndex)  //
    {
           
        
// **The number of records in one page
         int  intRecordPerPage  =   10 ;
        
        SqlConnection objCon 
=   new  SqlConnection(ConfigurationManager.ConnectionStrings[ " ConString " ].ConnectionString);
        SqlCommand objCmd 
=   new  SqlCommand();
        objCmd.Connection 
=  objCon;
        SqlDataReader objReader ;
        objCmd.CommandType 
=  CommandType.StoredProcedure;
        objCmd.CommandText 
=   " uspFetchProduct " ;
        objCmd.Parameters.Add(
new  SqlParameter( " @intCurrentPage " , intPageIndex));
        objCmd.Parameters.Add(
new  SqlParameter( " @intRecordPerPage " , intRecordPerPage));
        objCon.Open();
        objReader 
=  objCmd.ExecuteReader(CommandBehavior.CloseConnection);

       我设置一页显示10条记录。如果你想让用户自定义每页的记录数量,在你的网站中,你能添加一个选项设置值。用这个值来作为每页显示的记录数量。现在,我们在reader已经有了结果。创建一个StringBuilder 来存储创建的 HTML 。

代码
     StringBuilder sbHTML  =   new  StringBuilder();
        
// **********HEADER*********************
        sbHTML.Append( " <table><tr><td class='header'>SlNo</td><td class='header'>ProductID</td><td class='header'>Name</td><td class='header'>ProductNumber</td><td class='header'>StandardCost</td></tr> " );
        
// **********END HEADER*****************
        
// ***********LIST**********************
         bool  bRecordFound  =   false ;
        
while  (objReader.Read()) {
            bRecordFound 
=   true ;
            sbHTML.Append(
" <tr> " );

     在创建列表的HTML之后,我将它分配给一个保护的变量strList。

strList = sbHTML.ToString();

    现在完成我们主要要做的事情:如何去分页。对于分页,首先我们需要所有记录的总数量。能从reader中得到这个数量。

      objReader.NextResult();
        
int  intTotalRecords  =   0 ;
        
if  (objReader.Read()) {
            intTotalRecords 
= int .Parse(objReader[ 0 ].ToString());
        }

     现在,intTotalRecords变量包含了记录的总数量。第二个任务是去找页码数量。如下所示:

代码
       int  intReminder  =  intTotalRecords  %  intRecordPerPage;
        
// (100/10) mod=0 and (105/10) mod=5
         int  intTotalPages  =  intTotalRecords  /  intRecordPerPage;
        
// (100/10) =10 and 105\10 =10
         if  (intReminder  >   0 ) {
            
// (100/10) so 10 pages, if (105/10) means 11 pages
            intTotalPages  +=   1 ;
        }

     现在我们必须去找每一页的开始的一条记录和最后的一条记录。我们假设显示在页码列表中包含5页。 因此用户能获得First和Previous按钮,接下来是下5页的页码按钮,还有Next和Last按钮。

代码
         int  intPagesShowing  =   5 ;
        
//  5 pages will be showing in the list (1|2|3|4|5 then show next button)
         int  intStartPage  =   0 ;
        
int  intEndPage  =   0 ;
        intStartPage 
=  (intPageIndex  <=  intPagesShowing  ?   1  : intPageIndex);
        
        
if  (intTotalPages  >  intPagesShowing  &  intTotalPages  >  intStartPage) {
            intEndPage 
=  ((intStartPage  +  intPagesShowing  -   1 >  intTotalPages  ?  intTotalPages : (intStartPage  +  intPagesShowing  -   1 ));
        }
        
else  {
            intEndPage 
=  intTotalPages;
        }

    现在,我们要能通过页的索引和剩余的记录数目来隐藏和禁用First, Previous, Next, 和Last button。

代码
        bool  bShowFirst  =   false ;
        
bool  bShowPrevious  =   false ;
        
bool  bShowNext  =   false ;
        
bool  bShowLast  =   false ;
        
        
if  (intPageIndex  >   1 ) {
            bShowPrevious 
=   true ;
            bShowFirst 
=   true ;
        }
        
        
if  (intEndPage  <  intTotalPages) {
            bShowNext 
=   true ;
            bShowLast 
=   true ;
        }

    现在,我们能添加一个页数,它从第一页到最后一页。 

代码
         for  ( int  iPage  =  intStartPage; iPage  <=  intEndPage; iPage ++ ) {
            
// page numbers from current page to next recordsperpage (ie. 1-10)
             if  (intPageIndex  ==  iPage) {
                sbHTML.Append(
" <li class='active'> " );
                sbHTML.Append(
" <a> " );
            }
            
else  {
                sbHTML.Append(
" <li> " );
                sbHTML.Append(
" <a style='cursor:hand' onClick='javascript:doPaging( " );
                sbHTML.Append(iPage.ToString());
                sbHTML.Append(
" );'> " );
            }
            sbHTML.Append(iPage.ToString());
            sbHTML.Append(
" </a></li> " );
        }

    在实现了分页的HTML之后,在protected类型的字符串strPages中存储StringBuilder类型的值。分页就是就是如果页数超过一页,就仅仅显示一页。

代码
       if  (intTotalPages  >   1 ) {
            
// no paging is needed if only one page
            strPages  =  sbHTML.ToString();
            
// ***********END PAGING************************************************************
            
// ===============================================================================================================
            
        }

     如果使用这个方法,你不需要任何的数据源控件。我们创建和管理列表和分页的HTML。这项技术在你的页面上将给你带来最大的灵活性。

你可能感兴趣的:(asp.net)