构建高效Repeater分页(1)
...
Bing
...
ASP.NET
...
6
/1654
...
2 years 1 month ago
(由于最近在赶一个项目,所有没有太多时间来更新Blog,望见谅)在显示批量数据的时候,我们有比较多的选择,在ASP.NET里面,有着Datalist,GridView,Repeater这样三个常用的组件。其中GridView是使用最多的,其功能也最为强大,有自带的分页、排序等等功能,这对于高交互性的网站,这个是必需的。对于数据的统一处理,这个将是首选。但是如果不是处理数据呢?我们又该怎那么办?选择Datalist,这是个不错的主意,里面有自带的邦定功能,还有ItemTemplate供你这是个相当不错主意,如果你的水准够高,你甚至可以自己定义Edit ItemTemplate。但是我想很少有人会想到使用Repeater控件吧?Repater是最简单的控件,要帮定数据,排列数据还得自己编写Html,这个对于不喜欢使用Html的人来说更是可恶。
但是Repeater控件无疑是最为有效的控件,它的效率最高,同时它是唯一支持跨Template使用Html标签的控件,使用的好,不仅能够构建高效网站,还能构建强大的搜索功能,筛选功能和排序功能。下面我讲为大家讲述如何操作这个难使用的控件。
要是用Repeater,首先我们要解决的头一个问题就是分页的功能,如何实现分页呢?我个人比较喜欢使用PagedDataSource,并使用一个自定义RepeaterPagination类来封装Repeater行为。考虑到我们使用的
Repeater至少应该有PageFirst(最前页)、PagePre(上一页)、PageNext(下一页)、PageLast(最后一页),还要有自己选择PageIndex(页码)的功能,我们使用下面的代码图来表示我们的Pagination类来封装PagedDataSource(左边图形,右边代码)。
 | using System; using System.Data; using System.Configuration; using System.Web.UI; using System.Web.UI.WebControls;
namespace ChinaWebCat.Instance.Pagination { class Pagination : ChinaWebCat.Instance.Interface.IPagination { #region Members
private int _currentPageIndex; private int _pageSize; private int _pageCount; private PagedDataSource _pds;
#endregion
#region Constructor
public Pagination(DataView dataView) { _pds = new PagedDataSource(); _pds.DataSource = dataView; _pds.AllowPaging = true; _currentPageIndex = _pds.CurrentPageIndex; _pageSize = _pds.PageSize; _pageCount = _pds.PageCount; }
#endregion
#region Properties
public Int32 PageSize { get { return _pds.PageSize; } set { _pageSize = value; Update(); } }
public Int32 PageCount { get { return _pds.PageCount; } }
public Int32 CurrentPageIndex { get { return _pds.CurrentPageIndex; } set { _currentPageIndex = value; Update(); } }
public DataView PageDataSource { set { _pds.DataSource = value; Update(); } }
public PagedDataSource PagedDataSource { get { return _pds; } }
#endregion
#region Methods
public void PageIndexFirst() { if (!_pds.IsFirstPage) _currentPageIndex = 0; Update(); }
public void PageIndexPre() { if (!_pds.IsFirstPage) _currentPageIndex--; Update(); }
public void PageIndexNext() { if (!_pds.IsLastPage) _currentPageIndex++; Update(); }
public void PageIndexLast() { if (!_pds.IsLastPage) _currentPageIndex = _pds.PageCount; Update(); }
public void Update() { if (_pds.CurrentPageIndex != _currentPageIndex) _pds.CurrentPageIndex = _currentPageIndex; if (_pds.PageSize != _pageSize) _pds.PageSize = _pageSize; } #endregion } }
|
好了有了上面的代码,我们就可以顺利地封装了分页的功能,但是该功能尚未实现Repeater的分页,如何使得Repeater能分页呢?我们使用下面的代码来封装封装其分页的行为(
注意:我一再强调封装,这个是使得代码能够复用,好的封装能使得你一劳永逸)。考虑到我们的日后的更多功能,比如说筛选数据,搜索数据,给数据排序等等功能,我们有必要给出更多的属性和方法,我们将使用
RowFilter来筛选数据,OnSorting来给数据排序。请看下面的代码,左边是类图,右边是代码:

| using System; using System.Data; using System.Web.UI.WebControls;
namespace ChinaWebCat.Instance.Pagination { public class RepeaterPagination { #region Memembers
private Pagination _pagination; private Repeater _repeater; private DataView _dataView; private String _sortExpression;
#endregion
#region Constructor public RepeaterPagination(Repeater repeater, DataView dataView) { _pagination = new Pagination(dataView); _dataView = dataView; _repeater = repeater; } #endregion
#region Properties public Int32 PageSize { get { return _pagination.PageSize; } set { Int32 _pageIndex = CurrentPageIndex * PageSize; Int32 _currentPageIndex = _pageIndex / value; _pagination.PageSize = value; _pagination.CurrentPageIndex = _currentPageIndex; } }
public Int32 PageCount { get { return _pagination.PageCount; } }
public int CurrentPageIndex { get { return _pagination.CurrentPageIndex; } set { _pagination.CurrentPageIndex = value; } }
public Repeater Repeater { get { return _repeater; } set { _repeater = value; Update(); } }
public String RowFilter { set { _dataView.RowFilter = value; _pagination.PageDataSource = _dataView; } }
private String SortExpression { get { if (_sortExpression != null) { return _sortExpression; } else { return "date desc"; } } set { _sortExpression = value; } }
public DataView DataView { set { _pagination.PageDataSource = value; } }
#endregion
#region Methods public void PageIndexFirst() { _pagination.PageIndexFirst(); }
public void PageIndexPre() { _pagination.PageIndexPre(); }
public void PageIndexNext() { _pagination.PageIndexNext(); }
public void PageIndexLast() { _pagination.PageIndexLast(); }
public void Sorting(String sortExpression) { String[] currentSort = SortExpression.Split(' '); if (currentSort[0] != sortExpression) { _sortExpression = String.Format("{0} desc", sortExpression); _dataView.Sort = _sortExpression; } else { _sortExpression = String.Format("{0} {1}", sortExpression, currentSort[1] == "desc" ? "asc" : "desc"); _dataView.Sort = _sortExpression; } }
public void Update() { _repeater.DataSource = _pagination.PagedDataSource; _repeater.DataBind(); } #endregion } }
|
呵呵,是不是有点头晕了?没关系,弄懂了这个,保证你的对编程的领悟大增。好了两个类都封装好了,但是我们该如何显示出我们这个高效的Repeater分页呢?我们将采用两个Repeater,一个Repeater用来显示页码,当点击上面的一个页码的时候,下面的Repeatr将该页的内容显示出来。这个将如何实现呢?限于篇幅的原因,我将在下一节里讲解。
BEYOND
...
1 year 10 months ago
我也喜欢用repeater 以前都是直接页面中添加控件操作PagedDataSource 你的代码收下了,谢谢
=侍传说
...
2 years 1 month ago
早点帖出来看看。好学习学习
Bing
...
2 years 1 month ago
嘿嘿,那个啊,那是个Interface(接口)而已,我觉得给出旁边的那个类图应该是没问题的,不过看来我疏忽了,出下一个教程的时候我将补上!
By: =侍传说
...
2 years 1 month ago
class Pagination : ChinaWebCat.Instance.Interface.Ipagination
中的 ChinaWebCat.Instance.Interface.Ipagination应该是另一个类吧?
也一起贴出来吧。
=侍传说
...
2 years 1 month ago
等你的下一节。
=侍传说
...
2 years 1 month ago
不错。顶你一下。我看看。