about meWedia Ajax
构建高效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(左边图形,右边代码)。

PaginationDiagram.JPGusing 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来给数据排序。请看下面的代码,左边是类图,右边是代码:
DiagramRepeater.JPG
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
不错。顶你一下。我看看。
Name*
Email
Website
BoldItalicUnderlineJustify LeftJustify CenterJustify RightIndentOutdentBulled ListNumbered ListInsert LineCreate LinkUnlinkInsert Face
Submit