about meWedia Ajax
构建高效Repeater分页(2) ... Bing ... ASP.NET ... 3 /2351 ... 2 years 1 month ago
最近真的很忙,但是来到这看到留言“早点贴出来,好学习学习”,我就觉得有必要再继续更新下去。事情是永远没有止境的,但是可能自己的一点小小的提点就能帮助别人解决很大的难题,想想当初我学习的时候,大部分的帮助都得益于那些不知名的无私奉献的人,而我甚至连声谢谢都没有。如今我想我也应该尽自己所能给需要帮助的人任何力所能及的帮助,这是渴望的眼神,也是希望的眼神,这样的人往往不认识,但是却有相见恨晚的感觉,是知己的感觉。饮水思源……

好了,废话就不多罗索了,二十岁的小伙子废话多了可不好了。在上一节里我已经封装了两个类,Pagination和RepeaterPagination,其中Pagination 中有个小问题,不知道大家有没有注意,(很高兴居然有人看到了)。代码是这样的:class Pagination : ChinaWebCat.Instance.Interface.IPagination,如果不太清楚的人可以看看点击下面的链接先看看Article60.asp ,其实这个没有什么的,这个仅仅只是一个Interface。先看下面的代码:
DiagramIpagination.jpg
using System;
using System.Data;

namespace ChinaWebCat.Instance.Interface
{
interface IPagination
{
Int32 PageSize
{
get;
set;
}

Int32 PageCount
{
get;
}

Int32 CurrentPageIndex
{
get;
set;
}

DataView PageDataSource
{
set;
}

PagedDataSource PagedDataSource
{
get;
}

void PageIndexFirst();

void PageIndexPre();

void PageIndexNext();

void PageIndexLast();

void Update();
}
}

这是一个很简单的Interface,如果一个类在形成之前就有好的属性和方法规划,为每个类添加一个Interface是一个很好的习惯,它能帮助你排除一些不小心的失误,确保你的类的正确性,但是如果没有成熟的思考,建议先写出正常运行的类后,在添加Interface 也是很不错的注意

当然写完这个,实际上并没有任何的成果,那么最动人心弦的时刻要到来了,也意味着我们先前的任何准备将得到回报,完全的理论而无实际应用,我们只能为之叹息。如果您认真读过上一节的代码,您可能还记得在RepeaterPagination中有这样一个属性:PageCount。如果您的数据有5页,那么也意味着我们的页面上需要 1 2 3 4 5来导航对吧?! 那么我们将如何将PageCount和分页联系起来呢,因为页码的多少是动态显示的,那么我们也需要一个Repeater来动态显示这些数字。但是Repeater不能绑定数字啊?如何办?将数字变成数组不就好了?呵呵,完全正确。我们将使用下面的代码将数字变成数组。在看下面的代码前请看看本网站的主页上的分页:
页面端代码:
<asp:Repeater ID="Repeater2" runat="server" OnItemCommand="Repeater1_ItemCommand">
<ItemTemplate>
<asp:linkButton ID="linkButton1" runat="server" CommandArgument="<%# Container.DataItem %>"
Text="<%# Container.DataItem %>" ToolTip='<%# "PageTo"+Container.DataItem %>'>
</asp:linkButton>
</ItemTemplate>
</asp:Repeater>
服务器端代码:
//Before this function there is a _pageCount property,that's the RepeaterPagination's PageCount property
protected void SetPagination()
{
Int32[] _arrPageCount;
if (_arrPageCount == null)
{
_arrPageCount = new Int32[_pageCount];
for (Int32 i = 0; i < _pageCount; i++)
{
_arrPageCount[i] = i + 1;
}
}

//When the pageCount is less than 2,there is no need to set the pagination;

if (_arrPageCount.Length > 1)
{
Repeater2.DataSource = _arrPageCount;
Repeater2.DataBind();
//Before set the disable the page_one_button,because the page one is the default page
((linkButton)Repeater2.Controls[0].Controls[1]).Enabled = false;
}
else
{
Repeater2.DataSource = null;
Repeater2.DataBind();
}
}

这个是最简单的用来分页的代码,但是还没有完呢,仅仅只是显示提出了显示多少页的方法。我们得先看看下面的页面代码来实现数据邦定:

页面端代码:
<asp:Repeater ID="Repeater1" runat="server">
<HeaderTemplate>
<table border="0" cellpadding="0" cellspacing="0" style="width: 100%">
<tr>
<td>
AuthorName</td>
<td>
JoinDate</td>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("name") %>'></asp:Label><br />
</td>
<td>
Posted:<asp:Label ID="dateLabel" runat="server" Text='<%# Eval("date") %>'></asp:Label><br />
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
服务器端代码:
protected DataSet _data;
protected const String ThisPageSession = "forumPostData";

protected void Page_Load(object sender, EventArgs e)
{
if (CommonFunctions.CanConvertToInt(_fgID))
{
_data = (DataSet)Session[ThisPageSession];
if (_data == null)
{
//Never take care of the following red code, I just want to get the DataSet data from the database
_data = new ForumPostsMultiDataExec().LoadForumPostByID();
this.Session.Add(ThisPageSession, _data);
}
if (!IsPostBack)
{
Repeater1.DataSource = _data;
Repeater1.DataBind();
}
}
}

如果您对上面的代码很熟悉的话,那么我们将能很快地进入下面的讨论,因为我们这次探讨的问题稍微深一点,如果您什么都看不懂,那么还是先建议您学学ADO.NET2.0,这样对您的学习将轻松一点,同时也利于您从根本上理解这里的讨论。

好了,万事具备,只欠东风了。剩下的问题就是在于如何实现点击页码上的按钮的时候跳到相应的页面了。可能细心读者已经发现在实现分页的程序的时候有一个OnItemCommand="Repeater1_ItemCommand",在服务器端的代码里并没有这个事件,同时如果您善于思考的话会发现,我们的RepeaterPagination和Pagination这两个类怎么没使用上啊!如果您注意到了这些就应该很容易进入下面的学习,下面的学习将是水到渠成的。刚刚只是帮定了两个数据,对数据绑定先熟悉一下,同时分开将有助于您的理解,并有助于下面的学习。下面将是完整的代码。

页面端代码:
<asp:Repeater ID="Repeater2" runat="server" OnItemCommand="Repeater1_ItemCommand">
<ItemTemplate>
<asp:linkButton ID="linkButton1" runat="server" CommandArgument="<%# Container.DataItem %>"
Text="<%# Container.DataItem %>" ToolTip='<%# "PageTo"+Container.DataItem %>'>
</asp:linkButton>
</ItemTemplate>
</asp:Repeater>

<asp:Repeater ID="Repeater1" runat="server">
<HeaderTemplate>
<table border="0" cellpadding="0" cellspacing="0" style="width: 100%">
<tr>
<td>
AuthorName</td>
<td>
JoinDate</td>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("name") %>'></asp:Label><br />
</td>
<td>
Posted:<asp:Label ID="dateLabel" runat="server" Text='<%# Eval("date") %>'></asp:Label><br />
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
服务器端代码:
(别忘了加入命名空间namespace,如果您注意了,会发现在上一节的两个类是有命名空间的)
protected const String ThisPageSession = "forumPostData";
protected RepeaterPagination _repeaterPagination;
protected Int32 _pageCount;

protected void Page_Load(object sender, EventArgs e)
{
_repeaterPagination = (RepeaterPagination)Session[ForumPostsSession];
if (_repeaterPagination == null)
{
//Never take care of the following red code, I just want to get the DataSet data from the database
DataSet _data = new ForumPostsMultiDataExec().LoadForumPostsForumGroupData();
_repeaterPagination = new RepeaterPagination(Repeater1, _data.Tables[0].DefaultView);
this.Session.Add(ForumPostsSession, _repeaterPagination);
}
if (!IsPostBack)
{
_repeaterPagination.PageSize = 8;
_repeaterPagination.Repeater = Repeater1;
_pageCount = _repeaterPagination.PageCount;
SetPagination();
}

protected void SetPagination()
{
Int32[] _arrPageCount;
if (_arrPageCount == null)
{
_arrPageCount = new Int32[_pageCount];
for (Int32 i = 0; i < _pageCount; i++)
{
_arrPageCount[i] = i + 1;
}
}

//When the pageCount is less than 2,there is no need to set the pagination;

if (_arrPageCount.Length > 1)
{
Repeater2.DataSource = _arrPageCount;
Repeater2.DataBind();
//Before set the disable the page_one_button,because the page one is the default page
((linkButton)Repeater2.Controls[0].Controls[1]).Enabled = false;
}
else
{
Repeater2.DataSource = null;
Repeater2.DataBind();
}
}

protected void Repeater2_ItemCommand(object source, RepeaterCommandEventArgs e)
{
Int32 _currentPageIndex = Convert.ToInt32(((linkButton)e.CommandSource).CommandArgument) - 1;
Int32 _oldPageIndex;
try
{
_oldPageIndex = (Int32)Session[SessionoldPageIndex];
}
catch
{
_oldPageIndex = 0;
}

if (_currentPageIndex != _oldPageIndex)
{
//Disable the current page index and enable the old page index;
((linkButton)Repeater2.Controls[_oldPageIndex].Controls[1]).Enabled = true;
_repeaterPagination.CurrentPageIndex = _currentPageIndex;
_repeaterPagination.Repeater = Repeater1;
}
}
}

好了,终于完了,相信您也松了口气了,您现在可以自己测试一下了。由于所给代码和原本我的代码很不一样,所以没有经过具体的调试,可能中间有点误差,还望指出。这样的一个分页,仅仅只是一个很简单的开始,实现强大的分页还有很长的路,在以后我将逐渐教大家这些技巧是如何实现的,并逐步实现强大高效、高交互性的Repeater的分页。今天就到这了,我也着实是很累了。要想引领读者慢慢领会我们的思想是件很不容易的事,希望看的您能自己动手好好调试,相信您会学的更多!
Bing ... 2 years ago
呵呵,不知道您是谁!看的如此仔细,您说的前面一个错误是没有的,因为这个是用Session保存起来的,后面的一个错误已经纠正,谢谢您的提醒!!!
jsu ... 2 years ago
_repeaterPagination.CurrentPageIndex = _currentPageIndex; 前应加上_repeaterPagination.PageSize = 8;
另外 ((LinkButton)Repeater1.Controls[_oldPageIndex].Controls[1]).Enabled = true;中的Repeater1应该改为Repeater2
=侍传说 ... 2 years 1 month ago
不错学习了。先看看。
Name*
Email
Website
BoldItalicUnderlineJustify LeftJustify CenterJustify RightIndentOutdentBulled ListNumbered ListInsert LineCreate LinkUnlinkInsert Face
Submit