在Asp.net 应用开发中,Repeater 控件因其样式展现的灵活性而备受推崇.然而由于其没有分页功能,使得在实际运用中有所不便.
通过在网上四处搜罗一些相关的分页控件来看,SqlPager功能强大,可是感觉太烦.直到看到了.http://www.cnblogs.com/jecray/archive/2007/08/21/863395.aspx这篇文章,才觉得符合我所想要的.可惜的是,
不知道是不是jecray老兄太忙还是没有仔细测试过,和ObjectDataSource控件给合使用时,有一个小小的BUG.因此,我把它做了点小小的改动.同时为了方便其它的兄弟,就把它发出来做个纪念.在此,向jecray老兄致敬.
如果有空的话,再把它改成可以排序了.
下面是源码:
using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml.Linq;
using System.Web.UI.Design;
using System.ComponentModel;
using System.Reflection;
namespace DhzControl
{
[DefaultProperty("Text")]
[ToolboxData("<{0}:StudyezRepeater runat=server></{0}:StudyezRepeater >")]
public class StudyezRepeater : Repeater, INamingContainer
{
//页码变量
private int recordCount;
private int pageIndex;
private int pageSize = 5;
private string urlPara = "pageID";
[Bindable(true), DefaultValue(10)]
public int PageSize
{
get { return pageSize; }
set { pageSize = value; }
}
[Browsable(false)]
public int PageIndex
{
get { return pageIndex; }
set { pageIndex = value; }
}
[Browsable(false)]
public int RecordCount
{
get { return recordCount; }
set { recordCount = value; }
}
[Browsable(false)]
public int PageCount
{
get
{
if (RecordCount % PageSize == 0)
{
return RecordCount / PageSize;
}
else
{
return RecordCount / PageSize + 1;
}
}
}
//页面地址 构造url用
[Browsable(false)]
public string RawURL
{
get { return Page.Request.Path; }
}
//传递页码参数的名称
[Bindable(true), DefaultValue(typeof(String), "pageID")]
public string URLPara
{
get { return urlPara; }
set { urlPara = value; }
}
protected override void CreateChildControls()
{
//初始化 导航按钮
int.TryParse(HttpContext.Current.Request.QueryString[URLPara], out pageIndex);
if (PageIndex != 0)
PageIndex--;
this.SelectArguments.StartRowIndex = PageIndex * PageSize;
this.SelectArguments.MaximumRows = PageSize;
ObjectDataSource obj = (ObjectDataSource)this.Page.FindControl(this.DataSourceID);
obj.Selecting += new ObjectDataSourceSelectingEventHandler(ObjectDataSource_Selecting);
base.CreateChildControls();
}
protected virtual void ObjectDataSource_Selecting(object sender, ObjectDataSourceSelectingEventArgs e)
{
//此处可以采用缓存来管理,可以重写
ObjectDataSource obj = (ObjectDataSource)this.Page.FindControl(this.DataSourceID);
string countMethodName = obj.SelectCountMethod;
Type type = System.Web.Compilation.BuildManager.GetType(obj.TypeName, false, true);
MethodInfo methodInfo = type.GetMethod(countMethodName);
object[] parameters = null;
if (e.InputParameters != null && e.InputParameters.Count > 0)
{
int lc = e.InputParameters.Count;
parameters =new object[lc];
for (int i = 0; i < lc; i++)
{
parameters[i] = e.InputParameters[i];
}
}
if (methodInfo.IsStatic)
{
int.TryParse(methodInfo.Invoke(null, parameters).ToString (), out recordCount);
// RecordCount = recordCount;
}
else
{
object instance = Activator.CreateInstance(type);
int.TryParse(methodInfo.Invoke(instance, parameters).ToString(), out recordCount);
// RecordCount = recordCount;
}
}
protected override void Render(HtmlTextWriter writer)
{
SetPagerStatus();
//输出repeater
base.Render(writer);
//输出分页信息
writer.RenderBeginTag(HtmlTextWriterTag.Div);
CreateNavBar(writer);
writer.RenderEndTag();
}
protected virtual void CreateNavBar(HtmlTextWriter wirter)
{
//根据自已的要求可以重写.
for (int i = 1; i < PageCount; i++)
{
wirter.Write(string.Format("<a href='{0}?{1}={2}'>{2}</a> ", RawURL, URLPara, i));
}
wirter.Write(string.Format("<a href='{0}?{1}={2}'>{2}</a>", RawURL, URLPara, PageCount));
}
//设置分页状态
public void SetPagerStatus()
{
//如果没记录则不显示
if (PageCount == 0)
{
this.Visible = false;
return;
}
}
}
}
----------------------------------End-----------------
DataSrc.cs 文件
[Serializable]
public class Person
{
public Person()
{
//
// TODO: Add constructor logic here
//
}
public Person(int age, string name)
{
_name = name;
_age = age;
}
private string _name;
private int _age;
public string Name
{
get { return _name; }
set { _name = value; }
}
public int Age
{
get { return _age; }
set { _age = value; }
}
}
[DataObject(true)]
public class ObjDataSrc
{
/*Count方法和Persons方法也可以全部改成静态的以提升效率
*/
public ObjDataSrc()
{
}
public int Count(int age)
{
return 43;
}
[DataObjectMethod(DataObjectMethodType.Select )]
public Person[] Persons(int startRecord, int maxRecord, int age, string strOrder)
{
Person[] p = new Person[maxRecord];
for (int i = 1; i <= maxRecord; i++)
{
p[i - 1] = new Person(age, string.Format("{0}Name", startRecord + i - 1));
}
return p;
}
}
---------------------------------------END-------------------------
test.aspx 页面
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ Register TagPrefix="my" Namespace="DhzControl" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<my:StudyezRepeater ID="cx" runat="server" DataSourceID="src" PageSize="10">
<HeaderTemplate><table id="cv" style="background-color:Red ; width:400px; border-collapse:collapse ; border-width:thick"></HeaderTemplate>
<ItemTemplate>
<tr><td><%# Eval("Name") %> </td> <td><%# Eval("Age") %></td></tr>
</ItemTemplate>
<FooterTemplate></table></FooterTemplate>
</my:StudyezRepeater >
<asp:ObjectDataSource ID="src" runat="server" TypeName="ObjDataSrc" EnablePaging="true"
SelectCountMethod="Count" SelectMethod="Persons" SortParameterName="strOrder"
StartRowIndexParameterName="startRecord" MaximumRowsParameterName="maxRecord">
<SelectParameters>
<asp:Parameter Type="int32" Name="age" DefaultValue="10" Direction="Input" />
</SelectParameters>
</asp:ObjectDataSource>
</div>
</form>
</body>
</html>
----------------------------------现在,这个控件已经应用到自己的网站上www.studyez.com上面了.应用的时候都是重写了CreateNavBar------------------------