asp.net Repeater之非常好的数据分页
asp.net Repeater 控件是 .NET 框架提供的一种用于数据绑定的控件,它可以帮助我们轻松地将数据绑定到前端页面上。在使用 asp.net Repeater 控件时,如果需要对大量数据进行分页,我们通常可以通过自定义分页来实现。下面给出一个使用 asp.net Repeater 实现非常好的自定义分页的完整攻略,其中包含两个示例:
一、基本分页功能的实现
1. 实现基本的分页控制
要实现基本的分页控制,我们首先需要定义一个分页控制器,它包含以下控件:
<p class="pagination"> <asp:LinkButton ID="lnkPrev" runat="server" Text="<" CommandArgument="Prev" OnCommand="Page_Changed"></asp:LinkButton> <asp:Repeater ID="rptPager" runat="server"> <ItemTemplate> <asp:LinkButton ID="lnkPage" runat="server" CommandArgument='<%# Eval("PageIndex") %>' Text='<%# Eval("PageText") %>' OnClick="Page_Changed"></asp:LinkButton> </ItemTemplate> </asp:Repeater> <asp:LinkButton ID="lnkNext" runat="server" Text=">" CommandArgument="Next" OnCommand="Page_Changed"></asp:LinkButton></p>其中,lnkPrev 和 lnkNext 分别表示上一页和下一页的链接按钮,rptPager 表示分页导航条,它是一个 asp.net Repeater 控件。
2. 实现数据源绑定和分页数据筛选
对于数据源绑定和数据筛选,我们需要在后台代码中实现。首先,我们需要定义一个方法,用于分页查询数据库中的数据,并返回指定的数据集:
private void BindData(int pageIndex){ string sql = "SELECT * FROM TableName ORDER BY OrderColumn"; DataTable dt = DBHelper.ExecuteDataTable(sql); PagedDataSource pds = new PagedDataSource(); pds.DataSource = dt.DefaultView; pds.AllowPaging = true; pds.PageSize = 10; pds.CurrentPageIndex = pageIndex; lnkPrev.Enabled = !pds.IsFirstPage; lnkNext.Enabled = !pds.IsLastPage; rptPager.DataSource = BuildPagerItems(pds.PageCount, pageIndex); rptPager.DataBind();}其中,BuildPagerItems() 方法可以根据当前页码和总页数生成一个分页项的集合,具体实现见下文。
然后,我们需要在 Page_Changed 事件中响应分页事件,根据分页控制器的状态更新数据源:
protected void Page_Changed(object sender, CommandEventArgs e){ int pageIndex = int.Parse(e.CommandArgument.ToString()); if (e.CommandArgument.ToString() == "Next") { pageIndex = CurrentPageIndex + 1; } else if (e.CommandArgument.ToString() == "Prev") { pageIndex = CurrentPageIndex - 1; } CurrentPageIndex = pageIndex; BindData(CurrentPageIndex);}最后,我们需要在前端页面中定义一些辅助页面控件,用来记录当前页码、总页数等信息:
<asp:HiddenField ID="hdnCurrentPage" runat="server" /><asp:HiddenField ID="hdnTotalPages" runat="server" />值得注意的是,我们在 BindData() 方法中通过计算数据集中的总页数并将其存储到隐藏域控件中,以供后续使用。
3. 构建分页项集合
要构建分页项集合,我们需要定义一个 BuildPagerItems() 方法,该方法根据当前页码和总页数生成一个分页项的集合,代码如下:
private List<PagerItem> BuildPagerItems(int pageCount, int currentPageIndex){ List<PagerItem> items = new List<PagerItem>(); PagerItem item = new PagerItem(); item.PageIndex = 0; item.PageText = "首页"; items.Add(item); item = new PagerItem(); item.PageIndex = currentPageIndex - 1; item.PageText = "<"; items.Add(item); int start = 1; int end = pageCount; if (pageCount > 10) { start = Math.Max(currentPageIndex - 5, 1); end = Math.Min(currentPageIndex + 4, pageCount); if (end - start < 10) { start = end - 9; } } for (int i = start; i <= end; i++) { item = new PagerItem(); item.PageIndex = i - 1; item.PageText = i.ToString(); if (i == currentPageIndex + 1) { item.CssClass = "active"; } items.Add(item); } item = new PagerItem(); item.PageIndex = currentPageIndex + 1; item.PageText = ">"; items.Add(item); item = new PagerItem(); item.PageIndex = pageCount - 1; item.PageText = "末页"; items.Add(item); hdnCurrentPage.Value = currentPageIndex.ToString(); hdnTotalPages.Value = pageCount.ToString(); return items;}二、带有搜索栏的分页功能实现
1. 定义一个带有搜索栏的页面
要实现带有搜索栏的分页,我们需要在网页上方添加一个搜索栏,它包含一个文本框和一个搜索按钮:
<p class="search-bar"> <asp:TextBox ID="txtSearch" runat="server"></asp:TextBox> <asp:Button ID="btnSearch" runat="server" Text="搜索" OnClick="BtnSearch_Click" /></p>2. 在后台代码中实现数据按需绑定
为了实现按需绑定,我们需要在 BtnSearch_Click 事件中根据关键词执行查询操作,然后对查询结果进行分页:
protected void BtnSearch_Click(object sender, EventArgs e){ string sql = "SELECT * FROM TableName WHERE ColumnName LIKE '%" + txtSearch.Text + "%' ORDER BY OrderColumn"; DataTable dt = DBHelper.ExecuteDataTable(sql); PagedDataSource pds = new PagedDataSource(); pds.DataSource = dt.DefaultView; pds.AllowPaging = true; pds.PageSize = 10; pds.CurrentPageIndex = 0; CurrentPageIndex = 0; BindData(pds);}值得注意的是,我们在 BindData() 方法中传入了 PagedDataSource 对象,而不是直接传入页码,从而实现按需绑定的功能。
3. 更新分页项集合
在按需绑定的过程中,我们可能需要更新分页项集合,以反映新的总页数和当前页码。为此,我们可以在 BindData() 方法中添加一些适当的代码来实现:
hdnCurrentPage.Value = "0";hdnTotalPages.Value = pds.PageCount.ToString();rptPager.DataSource = BuildPagerItems(pds.PageCount, 0);rptPager.DataBind();示例代码
最后,附上示例代码:
private int CurrentPageIndex{ get { return int.Parse(hdnCurrentPage.Value); } set { hdnCurrentPage.Value = value.ToString(); }}protected void Page_Load(object sender, EventArgs e){ if (!IsPostBack) { BindData(CurrentPageIndex); }}private void BindData(int pageIndex){ string sql = "SELECT * FROM TableName ORDER BY OrderColumn"; DataTable dt = DBHelper.ExecuteDataTable(sql); PagedDataSource pds = new PagedDataSource(); pds.DataSource = dt.DefaultView; pds.AllowPaging = true; pds.PageSize = 10; pds.CurrentPageIndex = pageIndex; lnkPrev.Enabled = !pds.IsFirstPage; lnkNext.Enabled = !pds.IsLastPage; rptPager.DataSource = BuildPagerItems(pds.PageCount, pageIndex); rptPager.DataBind();}protected void Page_Changed(object sender, CommandEventArgs e){ int pageIndex = int.Parse(e.CommandArgument.ToString()); if (e.CommandArgument.ToString() == "Next") { pageIndex = CurrentPageIndex + 1; } else if (e.CommandArgument.ToString() == "Prev") { pageIndex = CurrentPageIndex - 1; } CurrentPageIndex = pageIndex; BindData(CurrentPageIndex);}private List<PagerItem> BuildPagerItems(int pageCount, int currentPageIndex){ List<PagerItem> items = new List<PagerItem>(); PagerItem item = new PagerItem(); item.PageIndex = 0; item.PageText = "首页"; items.Add(item); item = new PagerItem(); item.PageIndex = currentPageIndex - 1; item.PageText = "<"; items.Add(item); int start = 1; int end = pageCount; if (pageCount > 10) { start = Math.Max(currentPageIndex - 5, 1); end = Math.Min(currentPageIndex + 4, pageCount); if (end - start < 10) { start = end - 9; } } for (int i = start; i <= end; i++) { item = new PagerItem(); item.PageIndex = i - 1; item.PageText = i.ToString(); if (i == currentPageIndex + 1) { item.CssClass = "active"; } items.Add(item); } item = new PagerItem(); item.PageIndex = currentPageIndex + 1; item.PageText = ">"; items.Add(item); item = new PagerItem(); item.PageIndex = pageCount - 1; item.PageText = "末页"; items.Add(item); hdnCurrentPage.Value = currentPageIndex.ToString(); hdnTotalPages.Value = pageCount.ToString(); return items;}protected void BtnSearch_Click(object sender, EventArgs e){ string sql = "SELECT * FROM TableName WHERE ColumnName LIKE '%" + txtSearch.Text + "%' ORDER BY OrderColumn"; DataTable dt = DBHelper.ExecuteDataTable(sql); PagedDataSource pds = new PagedDataSource(); pds.DataSource = dt.DefaultView; pds.AllowPaging = true; pds.PageSize = 10; pds.CurrentPageIndex = 0; CurrentPageIndex = 0; BindData(pds); hdnCurrentPage.Value = "0"; hdnTotalPages.Value = pds.PageCount.ToString(); rptPager.DataSource = BuildPagerItems(pds.PageCount, 0); rptPager.DataBind();}注意事项:
PagerItem类是一个自定义的数据结构,用于表示分页项的数据,其中包含了PageIndex、PageText和CssClass三个属性;hdnCurrentPage和hdnTotalPages是两个用于记录当前页码和总页数的隐藏域控件;- 实际应用中,我们需要将
DBHelper.ExecuteDataTable()替换为自己的数据库访问操作代码; - 由于本示例中并没有实现样式,因此需要在
buildPagerItems()方法中添加样式逻辑,以调整分页项显示效果。