Simple Paging in Repeater and DataList Controls

Simple Paging in Repeater and DataList Controls  
      
   

[Rate this Article]

Introduction
Most of the times while creating database driven web pages like product listing, employee directory, etc. we display the data in grid format. ASP.NET has come up with Web Controls like DataGrid, DataList and Repeater that allow you to display your data in tabular format easily.

Amongst the above three Web Controls the DataGrid Control is the most advanced and supports paging, templates etc. The other two controls are used in places where you need more control over the rendering of your data. The DataList and Repeater Controls have very flexible templates that give you total control over the formatting of your data, but one of the major drawbacks of these controls is that they do not support paging!!

Paging simply means splitting data display (UI) over number of pages in order to facilitate easy to browse interface and minimize the data sent out to the client.
For example, you have a web page displaying your products listing. It would not be a good idea to show all the 1000+ products you are offering on the one single page, since it will make the page difficult to browse as well as it will take a lot of time to display on the clients browser due to the size of data (plus a heavy load on your server).
The second reason this is not a good idea is that the client would not want to know about all the products you are selling since the last 10 years, he might visit to page to look out for the new products that you are offering.
In such scenarios, you divide the display of data into different pages and then display say 10 - 20 items per page and provide the client with links to view additional pages, this is called Paging.
Remember we are using server-side scripting so you don't have to physically create all the pages, you just have to code one page in such a way that it keeps paging all the records.

Hence some of the merits of paging are:
1) Easy to browse pages.
2) Faster to load pages on client side since the amount to display per page is less.
3) Less load on the database server, since for every user you only pull out a limited amount of data, rather than pulling out all the records for each client.

As I mentioned before, the DataList and Repeater controls are very flexible and there would be a large number of places you might want to use these controls. Even though these controls do not support Paging internally, in this article I will display a method using which, you can easily enable simple paging (previous , next ) in your DataList and Repeater controls.

25 October 2002, Update: The small error in the BuildPagers method has been corrected. Thanks to all readers who pointed out the bug!

Requirements
1) ASP.NET v1
2) SQL Server 7.0/2000/MSDE
(Optional, I am going to use the Northwind database that installs with the .NET SDK)

Simple Paging in Repeater Control

1) Listing 1, shows the code for a normal page that selects all records from the Products table and displays it using the Repeater control.

<%@ Page Language="C#" debug="true" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<html>
<script language="C#" runat="server">
  void Page_Load( Object sender , EventArgs e)
  {
    //Build the Grid only if the page has been accessed for the first time
    if( !IsPostBack )
      BuildGrid();
  }

  public void BuildGrid()
  {
    SqlConnection myConnection =
          new SqlConnection(
      "server=(local)\\NetSDK;database=Northwind;Trusted_Connection=yes" );
    SqlDataAdapter myAdapter =
     new SqlDataAdapter(
      "SELECT ProductID, ProductName, QuantityPerUnit, UnitPrice FROM Products",
      myConnection);
    //Fill the DataSet
    DataSet ds = new DataSet();
    myAdapter.Fill(ds,"Products");
    //DataBind the Repeater
    MyRepeater.DataSource = ds.Tables["Products"].DefaultView;
    MyRepeater.DataBind();
  }
</script>
<body>
<h1>Products Listing</h1>
<form runat="server">
  <ASP:Repeater id="MyRepeater" runat="server">
      <HeaderTemplate>
        <table width="100%" border="1" cellpadding="1" cellspacing="2">
          <tr>
            <th>
              Product ID
            </th>
            <th>
              Product
            </th>
            <th>
              Quantity Per Unit
            </th>
            <th>
              Unit Price
            </th>
          </tr>

      </HeaderTemplate>

      <ItemTemplate>
        <tr>
          <td>
            <%# DataBinder.Eval(Container.DataItem, "ProductID") %>
          </td>
          <td>
            <%# DataBinder.Eval(Container.DataItem, "ProductName") %>
          </td>
          <td>
            <%# DataBinder.Eval(Container.DataItem, "QuantityPerUnit") %>
          </td>
          <td>
            <%# DataBinder.Eval(Container.DataItem, "UnitPrice", "$ {0}") %>
          </td>
        </tr>
      </ItemTemplate>

      <FooterTemplate>
        </table>
      </FooterTemplate>

  </ASP:Repeater>

</form>
</body>
</html>

Listing 1 - Simple Repeater Control
2) The first step to enable paging in this page is to add three hidden Html Controls that will maintain the values necessary for paging. You can add these controls below after your repeater control.

<input type="hidden" id="PageSize" value="10" runat="server">
<input type="hidden" id="CurrentPage" value="1" runat="server">
<input type="hidden" id="TotalSize" runat="server">
Listing 2 - Hidden Html Controls

The first control with the id PageSize is used to define the number of records you want to display per page. Current I have set it to display 10 records, you can set it to a value you wish.
The second control with the id CurrentPage is used to track the current page that's been displayed. Usually you want to start displaying the records from the first page so we set the value of this control to 1.
Lastly, the control with the id TotalSize is used to store the count of the total number of records available.

3) Next, we add two LinkButton controls that will enable navigation to the previous and next pages. Add these controls below the Repeater control definition.
Note: You might be tempted to include these controls within your Repeater control's FooterTemplate, but I advise you not to follow this approach since it will complicate matters much more while writing code to handle these buttons it will be very difficult to get a reference to these controls.

<asp:LinkButton id="Prev" Text="<< Previous" OnClick="Page_Repeater" runat="server" />  
<asp:LinkButton id="Next" Text="Next >>" OnClick="Page_Repeater" runat="server" />
Listing 3 - Link Buttons

Listing 3, defines the two LinkButtons with the id Prev and Next respectively. Feel free to change the Text property of these controls to something appropriate to your implementation. Also note that I have set the OnClick event of both these controls to one single event handling method called Page_Repeater. Listing 4 displays the Page_Repeater method code.

public void Page_Repeater( object sender, EventArgs e )
{
  //Check for Button clicked
  if( ((LinkButton)sender).ID == "Prev" )
  {
    //Check if we are on any page greater than 0
    if( ( int.Parse( CurrentPage.Value ) - 1 ) >=0 )
    {
      //Decrease the CurrentPage Value
      CurrentPage.Value = ( int.Parse( CurrentPage.Value ) - 1 ).ToString() ;
    }
  }
  else if( ((LinkButton)sender).ID == "Next" )
  {
    //Check if we can display the next page.
    if( ( int.Parse( CurrentPage.Value ) * int.Parse( PageSize.Value ) )
              < int.Parse( TotalSize.Value ) )
    {
      //Increment the CurrentPage value
      CurrentPage.Value = ( int.Parse( CurrentPage.Value ) + 1 ).ToString() ;
    }
  }
  //Rebuild the Grid
  BuildGrid();
}

Listing 4: Page_Repeater method

In the Page_Repeater method I first check which of the button was clicked.
If the Prev LinkButton was clicked, I check the value of the control with id CurrentPage. If the current value minus 1 is greater than equal to 0, it indicates I have previous pages to display. So I decrement the value of the control with id CurrentPage by 1.
If the Next LinkButton was clicked, I check out if the product of the controls with id's CurrentPage and the PageSize is less than the value of the control with id TotalSize, indicating that I have more pages to display. Hence I increment the value of the control with id CurrentPage.
Lastly, the BuildGrid method is given a call to re-build the Repeater.

4) The current BuildGrid method is configured to fetch all the records from the database. As I had stated earlier this is a bad practice and only limited records should be fetched each time to increase scalability of your web site. In Listing 5, below I modify the BuildGrid method so that it only pulls out the required records from the database.
In case you are data binding your control to a DataReader rather then a DataSet, then you will have to modify your SQL Statement appropriately so that only the required records are fetched.

  public void BuildGrid()
{
  SqlConnection myConnection =
    new SqlConnection(
      "server=(local)\\NetSDK;database=Northwind;Trusted_Connection=yes" );
  SqlDataAdapter myAdapter =
    new SqlDataAdapter(
      "SELECT ProductID, ProductName, QuantityPerUnit, UnitPrice FROM Products" ,
       myConnection);
  //Fill the DataSet
  DataSet ds = new DataSet();

  //Get the start Record Count
  //Remember database count is zero based so first decrease the value of
  //the current page
  int startRecord = ( int.Parse( CurrentPage.Value ) - 1 ) *
     int.Parse( PageSize.Value );
  //Fetch only the necessary records.
  myAdapter.Fill( ds , startRecord , int.Parse( PageSize.Value ) , "Products");

  //DataBind the Repeater  
  MyRepeater.DataSource = ds.Tables["Products"].DefaultView;
  MyRepeater.DataBind();

  //Second Part
  //Create a new Command to select the total number of records
  SqlCommand myCmd = new SqlCommand( "SELECT Count(*) FROM Products", myConnection );
  myConnection.Open();
  //retrieve the value
  TotalSize.Value = myCmd.ExecuteScalar().ToString() ;
  myConnection.Close();
}

Listing 5 - Modified BuildGrid method

As its clear from Listing 5, the only change I have made is that now I use a different overload of the Fill method that takes the start index and the number of records to fetch along with the standard DataSet and table name. Using this overload reduces the amount of data fetched from the database increasing the performance of your application.
Next, I construct and execute another query that returns the total number of records the database contains. This value is then stored to the control with id TotalSize. Remember that we cannot get the total records count from the DataSet since our updated Fill method only returns the necessary number of records. In your own implementation you will have to change this SQL query appropriately to return the number of records present in the database.
You can leave this second part out from your code if you just want to display a fixed number of pages and directly set the value of the control with id TotalSize manually. If the number of records does not change frequently you can encapsulate the second part in an if( !IsPostBack ) structure, so that the total number of records is only retrieved the first time the Repeater is built.

时间: 2024-10-31 11:25:28

Simple Paging in Repeater and DataList Controls的相关文章

ASP.NET 2.0数据教程之三十五:使用Repeater和DataList实现的主/从报表

返回"ASP.NET 2.0数据教程目录" 导言 在前面一章里我们学习了如何用两个页分别显示主/从信息.在 "主"页里我们用Repeater来显示category.每个category的name都 是一个链到"从"页的hyperlink.在从页里用一个两列的DataList显 示选中的category下的product. 本章我们将还是使用单页,在左边显示 category列表,category的名字用LinkButton显示.点击其中一个时页面

在ASP.NET 2.0中操作数据之三十五:使用Repeater和DataList单页面实现主/从报表_自学过程

导言 在前面一章里我们学习了如何用两个页分别显示主/从信息.在"主"页里我们用Repeater来显示category.每个category的name都是一个链到"从"页的hyperlink.在从页里用一个两列的DataList显示选中的category下的product.本章我们将还是使用单页,在左边显示category列表,category的名字用LinkButton显示.点击其中一个时页面postback,在右边以两列的DataList显示出相关的product

repeater或DataList控件简单应用

repeater或DataList控件 1.更改纯文本内容等 如果数据库教程里学生信息表中的sex字段用0和1来表示男女 但我们想repeat控件绑定后性别显示男或女而不是显示0或1 方法一:当然我们可以在SQL语句里判断并且转换 select (case sex when 0 then '男' else '女' end) AS sex from studentInfo 方法二:就是用到repeat 控件ItemDataBound()事件 <asp教程:Repearter ID="Repe

关于多层repeater,datagrid,datalist嵌套的示例

datagrid|示例 常常在CSDN上看到有网友问如何才能实现Repeater,DataList, DataGrid的嵌套问题,下面给出一个3层嵌套的示例,可以无限级嵌套下去 <ASP:REPEATER id="rpt_catalog" onitemdatabound="rpt_catalog_OnItemDataBound" runat="server"> <ITEMTEMPLATE>最顶层repeater,index

分别用DataGrid、Repeater、DataList绑定XML数据的例子

datagrid|xml|数据 data.aspx <%@ Import Namespace="System" %><%@ Import Namespace="System.IO" %><%@ Import Namespace="System.Xml" %><%@ Import Namespace="System.Data" %><%@ Import Namespace=&

5) Lastly, we need a method that enables and disables the LinkButtons depending on the number of records available, i.e. if you are on the first page, there is no use of displaying the link to go to the previous page - right ??   public void BuildPag

在ASP.NET 2.0中操作数据之四十一:DataList和Repeater数据分页_自学过程

导言 分页和排序是显示数据时经常用到的功能.比如,在一个在线书店里搜索关于ASP.NET 的书的时候,可能结果会是成百上千,而每页只列出十条.而且结果可以根据title(书名),price(价格),page count(页数),author name(作者)等来排序.我们在分页和排序报表数据 里已经讨论过, GridView, DetailsView, 和FormView 都有内置的分页功能,仅仅只需要勾一个checkbox就可以开启.GridView 还支持内置的排序. 不幸的是,DataLi

asp.net DataList与Repeater用法区别_实用技巧

性能方面 Repeater比DataList要好一些,如果不是很大数据量的话,这点差别是体现不来的. 易用性方面 Repeater与DataList后台的数据绑定都很简单,DataSource=... DataBind()就OK了 但是DataList在对布局的操作上更加的方便一些,如它提供了SelectItemTemplate,EidtItemTemplate等,但是Repeater却没有,所以对于有选中颜色或者背景图片改变,最好选用DataList.如果用Repeater就需javascri

在ASP.NET 2.0中操作数据之四十五:DataList和Repeater里的自定义Button_自学过程

导言 在前面关于DataList 和Repeater 的7章教程里,我们分别创建了只读和可以编辑删除的例子.为了让DataList有编辑和删除的功能,我们在ItemTemplate里添加了一些button,当点击时,引起postback,并根据button的CommandName属性激发相关的事件.例如,添加一个CommandName为"Edit"的button,在postback时会激发EditCommand事件,如果CommandName为"Delete"则激发