概述

在网上看到不少的这方面的例子,使Repeater控件象ListView控件一样支持DataPager分页。但是我试了不少,都失败了。所以我就花点时间来自己写了一个。下面是我的解决方案。

代码介绍

首先,我们建立一个用户控件,取名​​DataPagerRepeater。​​使其继承自​​Repeater​​ 并引用​​System.Web.UI.WebControls.IPageableItemContainer​​ 命名空间。(同时添加​​System.Web.Extensions引用​​)并输入以下代码

[ToolboxData("<{0}:DataPagerRepeater runat="server" 
PersistentDataSource=true></{0}:DataPagerRepeater>")]

public class DataPagerRepeater : Repeater,
System.Web.UI.WebControls.IPageableItemContainer, INamingContainer
{

public int MaximumRows { get { return ViewState["_maximumRows"] != null ?
(int)ViewState["_maximumRows"] : -1; } }
public int StartRowIndex { get { return ViewState["_startRowIndex"] != null ?
(int)ViewState["_startRowIndex"] : -1; } }
public int TotalRows { get { return ViewState["_totalRows"] != null ?
(int)ViewState["_totalRows"] : -1; } }

public bool PersistentDataSource {
get { return ViewState["PersistentDataSource"] != null ?
(bool)ViewState["PersistentDataSource"] : true; }
set { ViewState["PersistentDataSource"] = value; }
}

protected override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);

if (Page.IsPostBack)
{
if (PersistentDataSource && ViewState["DataSource"] != null)
{
this.DataSource = ViewState["DataSource"];
this.DataBind();
}
}
}

public void SetPageProperties(int startRowIndex, int maximumRows, bool databind)
{
ViewState["_startRowIndex"] = startRowIndex;
ViewState["_maximumRows"] = maximumRows;

if (TotalRows > -1)
{
if (TotalRowCountAvailable != null)
{
TotalRowCountAvailable(this,
new PageEventArgs((int)ViewState["_startRowIndex"],
(int)ViewState["_maximumRows"], TotalRows));
}
}
}

protected override void OnDataPropertyChanged()
{
if (MaximumRows != -1)
{
this.RequiresDataBinding = true;
}
else
base.OnDataPropertyChanged();
}

protected override void RenderChildren(HtmlTextWriter writer)
{
if (MaximumRows != -1)
{
foreach (RepeaterItem item in this.Items)
{
if (item.ItemType == ListItemType.Item ||
item.ItemType == ListItemType.AlternatingItem)
{
item.Visible = false;

if (item.ItemIndex >= (int)ViewState["_startRowIndex"] &&
item.ItemIndex <= ((int)ViewState["_startRowIndex"] +
(int)ViewState["_maximumRows"]))
{
item.Visible = true;
}
}
else
{
item.Visible = true;
}
}
}
base.RenderChildren(writer);
}

public override void DataBind()
{
base.DataBind();

if (MaximumRows != -1)
{
int i = 0;
foreach (object o in GetData())
{
i++;
}
ViewState["_totalRows"] = i;

if(PersistentDataSource)
ViewState["DataSource"] = this.DataSource;
SetPageProperties(StartRowIndex, MaximumRows, true);
}
}

protected override System.Collections.IEnumerable GetData()
{
return base.GetData();
}

public event System.EventHandler<PageEventArgs> TotalRowCountAvailable;
}


编译后在asp.net WebForm中使用方法如下:

<cc1:DataPagerRepeater ID="rep1" 
runat="server" PersistentDataSource="true">
<HeaderTemplate > <div></HeaderTemplate>
<ItemTemplate>
<div >
<%# Eval("Value") %>
</div>
</ItemTemplate>
<FooterTemplate></div></FooterTemplate>
</cc1:DataPagerRepeater>

<asp:DataPager ID="DataPager1"
PagedControlID="rep1" PageSize="2" runat="server"><Fields><asp:NextPreviousPagerField ButtonType="Button" ShowFirstPageButton="True"
ShowNextPageButton="False" ShowPreviousPageButton="False" />

<asp:NumericPagerField /><asp:NextPreviousPagerField ButtonType="Button" ShowLastPageButton="True"
ShowNextPageButton="False" ShowPreviousPageButton="False" /></Fields>

</asp:DataPager>


在后台事件中添加以下代码:

protected void Page_Load(object sender, EventArgs e) 
{
if(!IsPostBack)
{
System.Collections.SortedList SL = new System.Collections.SortedList();

SL.Add("val1","Text1");
SL.Add("val2","Text2");
SL.Add("val3","Text3");
SL.Add("val4","Text4");
SL.Add("val5","Text5");
SL.Add("val6","Text6");
SL.Add("val7","Text7");
SL.Add("val8","Text8");
SL.Add("val9","Text9");

rep1.DataSource = SL;
rep1.DataBind();
}
}