English Version: http://dflying.dflying.net/1/archive/127_paging_your_list_using_aspnet_atlas_pagenavigator_control.html
In this series, I will introduce some of the more advanced controls in Atlas Sys.UI.Data, including:
Sys.UI.Data.ListView : Display list data using ASP.NET Atlas ListView control
Sys.UI.Data.ItemView: Display individual data from a collection using the ASP.NET Atlas ItemView control
Sys.UI.Data.DataNavigator: Use the ASP.NET Atlas PageNavigator control to implement client-side paging navigation
Sys.UI.Data.SortBehavior: To be continued
Sys.UI.Data.XSLTView: To be continued This is the third article: Use the ASP.NET Atlas PageNavigator control to implement client-side paging navigation and put all records on one page is definitely not a good idea, especially when you have hundreds or thousands of records. Your users need to keep dragging the scroll bar or even using Control+F to find the content they are looking for, which will bring a very poor user experience. At this time, it will be much more user-friendly to display the data in paging. Some ASP.NET server-side controls have built-in paging and page navigation capabilities, such as DataGrid and GridView. Similarly, the Atlas client control Sys.UI.Data.DataNavigator also provides similar functions, which will greatly improve our development efficiency.
The DataNavigator control will work with the DataView (please refer to: Control introduction under Atlas namespace Sys.Data - DataView and DataFilter) control. We know that the DataView control does not provide page navigation related methods, so we can only directly set its pageIndex property to implement navigation. Although it is not difficult, in many cases this is not a good idea, because many careless developers like me often forget to check the boundary value of pageIndex, causing unnecessary trouble. This is one of the reasons why Atlas provides the DataNavigator control. The DataNavigator control will serve as a proxy for the DataView control and provide an easy-to-use page navigation interface.
The DataNavigator object has only one attribute:
dataView: a reference to a DataView object. This DataNavigator will apply the page navigation operation to it. You should always specify this property.
In addition, to use the DataNavigator control, you also need to provide some Atlas Buttons with some specified commandName properties to trigger the corresponding page navigation operations. The parent property of these Buttons should be set to this DataNavigator control to ensure that the DataNavigator can capture the commands issued by these Buttons.
You can specify the commandName attribute of your Button as the following five strings, each with a different meaning:
page: Convert the current page index to the value specified in the command argument. With this command we can quickly change the index of the page.
nextpage: Switch to the next page (if the next page exists).
previouspage: Switch to the previous page (if a previous page exists).
firstpage: switch to the first page.
lastpage: switch to the last page.
OK, the boring introduction like MSDN is over here, let us get familiar with the use of DataNavigator through an example.
First we need to expose a Web Service so that the Atlas page can use it. The Web Service will return 100 records. The following is the code of this Web Service, which is very easy to understand and will not be repeated here.
Web Service
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Web;
using System.Web.Caching;
using System.Web.Services;
using System.Web.Services.Protocols;
using Microsoft.Web.Services;
//
// For simplicity this example demonstraes storing and manipulating
// the data objects in memory. A database can also be used.
//
[WebService(Namespace = " http://tempuri.org/ ")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class MyDataService : DataService
{
static List<Entry> _data;
static object _dataLock = new object();
private static List<Entry> Data
{
get
{
if (_data == null)
{
lock(_dataLock)
{
if (_data == null)
{
_data = new List<Entry>();
for (int i = 0; i < 100; i++)
{
_data.Add(new Entry(i, "Dflying " + i.ToString(), string.Format(" Dflying{0}@dflying.net ", i.ToString())));
}
}
}
}
return _data;
}
}
[DataObjectMethod(DataObjectMethodType.Select)]
public Entry[] SelectRows()
{
return MyDataService.Data.ToArray();
}
}
public class Entry
{
private string _name;
private string _email;
private int _id;
[DataObjectField(true, true)]
public int Id
{
get { return _id; }
set { _id = value; }
}
[DataObjectField(false)]
[DefaultValue("New row")]
public string Name
{
get { return _name; }
set { _name = value; }
}
[DataObjectField(false)]
[DefaultValue("")]
public string Email
{
get { return _email; }
set { _email = value; }
}
public Entry()
{
_id = -1;
}
public Entry(int id, string name, string description)
{
_id = id;
_name = name;
_email = description;
}
}
Then, in the ASPX page, we need to consider and define the following four parts:
a ScriptManager control to contain the Atlas Framework related script files necessary for the page. Typically, this is what every Atlas page must include.
A place holder div (id is dataContents, see code). Atlas will place the rendered paginated ListView here.
A div (DataNavigator control) as a container, and a set of buttons (command buttons) contained in it, are used to implement page navigation functions.
A hidden div used to place the ListView template.
The following is the code for the above four parts. Regarding the template of the ListView control, please refer to my article: Using the ASP.NET Atlas ListView control to display list data
<!-- ScriptManager -->
<atlas:ScriptManager runat="server" ID="scriptManager" />
<!-- Element for paged ListView (container) -->
<div id="dataContents">
</div>
<!-- PageNavigator -->
<div id="pageNavigator">
<input type="button" id="btnFirstPage" value="<<" />
<input type="button" id="btnPrevPage" value="<" />
<span id="lblPageNumber"></span> / <span id="lblPageCount"></span>
<input type="button" id="btnNextPage" value=">" />
<input type="button" id="btnLastPage" value=">>" />
</div>
<!-- Templates -->
<div style="visibility: hidden; display: none">
<table id="myList_layoutTemplate" border="1" cellpadding="3" style="width:20em;">
<thead>
<tr>
<td><span>No.</span></td>
<td><span>Name</span></td>
<td><span>Email</span></td>
</tr>
</thead>
<!-- Repeat Template -->
<tbody id="myList_itemTemplateParent">
<!-- Repeat Item Template -->
<tr id="myList_itemTemplate">
<td><span id="lblIndex" /></td>
<td><span id="lblName" /></td>
<td><span id="lblEmail" /></td>
</tr>
</tbody>
</table>
<!-- Empty Template -->
<div id="myList_emptyTemplate">
No Data
</div>
</div>
Finally, it is time to write the XML script definition for Atlas, which has the following five parts:
Part 1: Atlas client control DataSource, used to obtain data from the Web Service we defined above.
<dataSource id="dataSource" autoLoad="true" serviceURL="MyDataService.asmx" />
Part 2: A DataView control (please refer to: Introduction to controls under Atlas namespace Sys.Data - DataView and DataFilter), used to page the 100 pieces of data obtained in the first part.
<dataView id="view" pageSize="12">
<bindings>
<binding dataContext="dataSource" dataPath="data" property="data" />
</bindings>
</dataView>
Part 3: A ListView control (please refer to: Using the ASP.NET Atlas ListView control to display list data), used to display paginated data.
<listView id="dataContents" itemTemplateParentElementId="myList_itemTemplateParent" >
<bindings>
<binding dataContext="view" dataPath="filteredData" property="data"/>
</bindings>
<layoutTemplate>
<template layoutElement="myList_layoutTemplate"/>
</layoutTemplate>
<itemTemplate>
<template layoutElement="myList_itemTemplate">
<label id="lblIndex">
<bindings>
<binding dataPath="$index" transform="Add" property="text"/>
</bindings>
</label>
<label id="lblName">
<bindings>
<binding dataPath="Name" property="text"/>
</bindings>
</label>
<label id="lblEmail">
<bindings>
<binding dataPath="Email" property="text"/>
</bindings>
</label>
</template>
</itemTemplate>
<emptyTemplate>
<template layoutElement="myList_emptyTemplate"/>
</emptyTemplate>
</listView>
Part 4: DataNavigator control and command buttons. Notice that we have four buttons here, each with a different commandName attribute, which also corresponds to an operation of DataNavigator on DataView. At the same time, the parent properties of these buttons are set to this DataNavigator object.
<dataNavigator id="pageNavigator" dataView="view"/>
<button id="btnFirstPage" parent="pageNavigator" command="FirstPage" />
<button id="btnPrevPage" parent="pageNavigator" command="PreviousPage">
<bindings>
<binding property="enabled" dataPath="hasPreviousPage"/>
</bindings>
</button>
<button id="btnNextPage" parent="pageNavigator" command="NextPage">
<bindings>
<binding property="enabled" dataPath="hasNextPage"/>
</bindings>
</button>
<button id="btnLastPage" parent="pageNavigator" command="LastPage" />
Part 5: Two Labels, showing the total number of pages and the serial number of the current page respectively.
<label id="lblPageNumber">
<bindings>
<binding dataContext="view" property="text" dataPath="pageIndex" transform="Add"/>
</bindings>
</label>
<label id="lblPageCount">
<bindings>
<binding dataContext="view" property="text" dataPath="pageCount"/>
</bindings>
</label>
OK, test it in the browser: