asp.net 无刷新翻页就是这么简单

  个人喜欢用Repeater,因其简洁,此AjaxPager定向为Repeater!

  一步一步看来:

  代码

  

复制代码 代码如下:

  [DefaultProperty("TotalRecord"),

  ToolboxData("<{0}:AjaxPager runat=server></{0}:AjaxPager>")]

  public class AjaxPager : WebControl,ICallbackEventHandler

  {

  public AjaxPager()

  : base(HtmlTextWriterTag.Div)

  {

  this.Load += new EventHandler(AjaxPager_Load);

  }

  void AjaxPager_Load(object sender, EventArgs e)

  {

  string script = "function AjaxPagerCallBack(returnData){var parts =returnData.split('[_]'); document.getElementById('" + this.UniqueID.Replace ('$','_') + "').innerHTML = parts[0];document.getElementById('" + Info.ContainID + "').innerHTML=parts[1]}";

  this.Page.ClientScript.RegisterClientScriptBlock(this.Page.GetType(), "AjaxPagerCallBack", script, true);

  }

  }

  这里在Load事件里向页面注册了一段JS,AjaxPagerCallBack方法做两个操作,把自己表现的数据放入自己在客户端生成的DIV容器里,即id为this.UniqueID.Replace('$','_')的div,ClientID好像也可以!哈,一时糊涂!第二步就是把分页数据放到id为Info.ContainID的div中,Info对象下面会说到。

  变量属性

  

复制代码 代码如下:

  #region 变量

  private string _BarBackGroundColor = "#FFFFFF";

  private string _BarLinkColor = "Navy";

  private string _BarCurrentColor = "#EEEEEE";

  private int _TotalRecord = 50;

  private int _TotalPage = 0;

  private int _CurrentIndex = 1;

  private int _ItemSize = 10;

  private PageInfo _Info=new PageInfo ();

  #endregion

  #region 属性

  #region 外观

  [Description("分页背景色"),

  Bindable(true),

  Category("外观"),

  DefaultValue("#FFFFFF")]

  public string BarBackGroundColor

  {

  get { return _BarBackGroundColor; }

  set { _BarBackGroundColor = value; }

  }

  [Description("分页条链接数字颜色"),

  Bindable(true),

  Category("外观"),

  DefaultValue("Navy")]

  public string BarLinkColor

  {

  get { return _BarLinkColor; }

  set { _BarLinkColor = value; }

  }

  [Description("分页条当前页数字颜色"),

  Bindable(true),

  Category("外观"),

  DefaultValue("#EEEEEE")]

  public string BarCurrentColor

  {

  get { return _BarCurrentColor; }

  set { _BarCurrentColor = value; }

  }

  #endregion

  #region 行为

  [Description("总记录数"),

  Category("行为"),

  DefaultValue(50)]

  public int TotalRecord

  {

  get { return _TotalRecord; }

  set

  {

  _TotalRecord = value;

  }

  }

  [Description("总页数"),

  Category("行为"),

  DefaultValue(0)]

  public int TotalPage

  {

  get { return _TotalPage; }

  }

  [Description("Bar的大小"),

  Category("行为"),

  DefaultValue(10)]

  public int BarSize

  {

  get { return _ItemSize; }

  set

  {

  foreach (char c in System.Convert.ToString(value))

  {

  if (!Char.IsNumber(c))

  {

  _ItemSize = 10;

  break;

  }

  }

  _ItemSize = value;

  }

  }

  [Description("当前页值"),

  Category("行为"),

  DefaultValue(1)]

  public int PageIndex

  {

  get { return _CurrentIndex; }

  set { _CurrentIndex = value; }

  }

  #endregion

  public PageInfo Info

  {

  get { return _Info; }

  set { _Info = value; }

  }

  #endregion

  这里自不必细说。其中的PageInfo如下:

  PageInfo

  

复制代码 代码如下:

  [Serializable]

  public class PageInfo

  {

  private string _RepeaterUniqueID;

  private string _ContainID="AjaxData";

  private string _TableName = string.Empty;

  private string _IdentityField = "ID";

  private int _PageSize = 10;

  private string _Fields = "*";

  private bool _IsDesc = true;

  private string _Content = string.Empty;

  private string _ConnectStringName = string.Empty;

  public string RepeaterUniqueID

  {

  get { return _RepeaterUniqueID; }

  set { _RepeaterUniqueID = value; }

  }

  public string ContainID

  {

  get { return _ContainID; }

  set { _ContainID = value; }

  }

  public int PageSize

  {

  get { return _PageSize; }

  set

  {

  _PageSize = int.Parse(value.ToString());

  }

  }

  public string TableName

  {

  get { return _TableName; }

  set { _TableName = value; }

  }

  public string IdentityField

  {

  get { return _IdentityField; }

  set { _IdentityField = value; }

  }

  public string Fields

  {

  get { return _Fields; }

  set { _Fields = value; }

  }

  public bool IsDesc

  {

  get { return _IsDesc; }

  set { _IsDesc = value; }

  }

  public string Content

  {

  get { return _Content; }

  set { _Content = value; }

  }

  public string ConnectStringName

  {

  get { return _ConnectStringName; }

  set { _ConnectStringName = value; }

  }

  }

  这是标记为Serializable,是因为下面要保存到ViewState里。

  辅助方法

  

复制代码 代码如下:

  private string GetContents()

  {

  this._TotalPage = ((this.TotalRecord / this.Info.PageSize) * this.Info.PageSize == this.TotalRecord) ? (this.TotalRecord / this.Info.PageSize) : ((this.TotalRecord / this.Info.PageSize) + 1);

  int BeginRecord = (this.PageIndex - 1) * this.Info.PageSize + 1;

  int EndRecord = Math.Min(this.PageIndex * this.Info.PageSize, this.TotalRecord);

  string PageInfo = string.Format("[每页<span style='color:#CC0000'>{0}({1}-{2})</span>条  共<span style='color:#CC0000'>{3}</span>条<span style='color:#CC0000'>{4}</span>页]", Info.PageSize, BeginRecord, EndRecord, this.TotalRecord, this.TotalPage);

  StringBuilder PageListStr = new StringBuilder();

  string PageIndexColor = "#000000";

  int SingleNumber = this.TotalPage - (TotalPage / BarSize) * BarSize;

  int IntPageForMax = (this.PageIndex - 1) / BarSize;

  int MinInt = (1 + BarSize * IntPageForMax);

  int MaxInt = ((IntPageForMax + 1) * BarSize) > TotalPage ? TotalPage : ((IntPageForMax + 1) * BarSize);

  if (this.TotalRecord == 0 || this.TotalPage == 0)

  {

  PageListStr.AppendFormat("<span style='color:'{0};margin:auto 3px;'>0</span>", PageIndexColor);

  PageListStr.AppendFormat(" [共<span style='color:#CC0000'>0</span>页/当前第<span style='color:#CC0000'>0</span>页 共<span style='color:#CC0000'>0</span>条记录,当前记录数<span style='color:#CC0000'>0</span>到<span style='color:#CC0000'>0</span>]");

  return PageListStr.ToString();

  }

  else

  {

  if (this.TotalPage <= this.BarSize)

  {

  for (int i = 1; i <= TotalPage; i++)

  {

  PageIndexColor = PageIndex == i ? "#CC0000" : "#000000";

  if (PageIndex == i)

  PageListStr.AppendFormat("<a id='{0}' style='color:{1};margin:auto 3px;'>{2}</a>", this.UniqueID, PageIndexColor, i);

  else

  PageListStr.AppendFormat("<a id='{0}' style='color:{1};margin:auto 3px;' href=\"javascript:{2}\">{3}</a>", this.UniqueID, PageIndexColor, Page.ClientScript.GetCallbackEventReference(this, i.ToString(),"AjaxPagerCallBack",null), i);

  }

  PageListStr.AppendFormat(" {0}", PageInfo);

  return PageListStr.ToString();

  }

  else

  {

  for (int i = MinInt; i <= MaxInt; i++)

  {

  PageIndexColor = PageIndex == i ? "#CC0000" : "#000000";

  if (PageIndex == i)

  PageListStr.AppendFormat("<a id={0}' style='color:{1};margin:auto 3px;'>{2}</a>", this.UniqueID, PageIndexColor, i);

  else

  PageListStr.AppendFormat("<a id='{0}' style='color:{1};margin:auto 3px;' href=\"javascript:{2}\">{3}</a>", this.UniqueID, PageIndexColor, Page.ClientScript.GetCallbackEventReference(this, i.ToString(), "AjaxPagerCallBack", null), i);

  }

  if (PageIndex <= BarSize && TotalPage > BarSize)

  {

  PageListStr.AppendFormat("<a id='{0}' href=\"javascript:{1}\">下一页</a>", this.UniqueID, Page.ClientScript.GetCallbackEventReference(this, System.Convert.ToString(BarSize + 1), "AjaxPagerCallBack", null));

  }

  if (this.PageIndex > BarSize && (TotalPage - this.PageIndex) >= SingleNumber)

  {

  int MultiMinPageIndex = (IntPageForMax * BarSize);

  int MultiMaxPageIndex = ((IntPageForMax + 1) * BarSize) + 1;

  PageListStr.Insert(0, string.Format("<a id='{0}' href=\"javascript:{1}\">上一页</a>", this.UniqueID, Page.ClientScript.GetCallbackEventReference(this, MultiMinPageIndex.ToString(),"AjaxPagerCallBack",null)));

  PageListStr.AppendFormat("<a id='{0}' href=\"javascript:{1}\">下一页</a>", this.UniqueID, Page.ClientScript.GetCallbackEventReference(this, MultiMaxPageIndex.ToString(),"AjaxPagerCallBack",null));

  }

  if (PageIndex > 10 && (TotalPage - PageIndex) < SingleNumber)

  {

  int MultiMinPageIndex = (IntPageForMax * BarSize);

  PageListStr.Insert(0, string.Format("<a id='{0}' href=\"javascript:{1}\">上一页</a>", this.UniqueID, Page.ClientScript.GetCallbackEventReference(this, MultiMinPageIndex.ToString(), "AjaxPagerCallBack", null)));

  }

  PageListStr.AppendFormat(" {0}", PageInfo);

  return PageListStr.ToString();

  }

  }

  }

  public void BindData()

  {

  Repeater rpt = getRpt();

  rpt.Visible = true;

  SqlHelper helper;

  helper = this.Info.ConnectStringName.IsNullOrEmpty() ? new SqlHelper() : new SqlHelper(Info.ConnectStringName);

  if (this.Info.RepeaterUniqueID.IsNullOrEmpty())

  {

  throw new Exception("必须给Info的RepeaterUniqueID属性赋值");

  }

  int count = 0;

  DataTable dt = helper.GetPageData(Info.TableName, Info.Fields, Info.IdentityField, Info.PageSize, PageIndex, Info.IsDesc, Info.Content, out count);

  this.TotalRecord = count;

  rpt.DataShow(dt);

  }

  private Repeater getRpt()

  {

  return this.Page.FindControl(this.Info.RepeaterUniqueID) as Repeater;

  }

  先感谢一下写那个Pager的人,GetContents(得到自己分页后的HTML)里我只做了少许改动,要不然还得细细算来!!

  BindData(用到了我的SqlHelper)是利用为服务器的DataBind()方法把数据放到repeater里,只是不让它呈示,嘿嘿!

  getRpt只是找到Repeater引用

  维护视图状态

  

复制代码 代码如下:

  #region 维护视图状态

  protected override void LoadViewState(object savedState)

  {

  Triplet tp = savedState as Triplet;

  this.TotalRecord = Convert.ToInt32(tp.Third);

  this.Info = tp.Second as PageInfo;

  base.LoadViewState(tp.First);

  }

  protected override object SaveViewState()

  {

  Triplet tp = new Triplet();

  tp.First = base.SaveViewState();

  tp.Second = Info;

  tp.Third = this.TotalRecord;

  return tp;

  }

  #endregion

  这里也不必说,只是PageInfo一定要能Serializable。

  重写方法

  

复制代码 代码如下:

  #region 重写方法

  protected override void RenderContents(HtmlTextWriter writer)

  {

  writer.Write(GetContents());

  base.RenderContents(writer);

  }

  protected override void AddAttributesToRender(HtmlTextWriter writer)

  {

  writer.AddStyleAttribute("White-space", "nowrap");

  writer.AddStyleAttribute("padding-top", "2px");

  writer.AddStyleAttribute("padding-bottom", "2px");

  writer.AddStyleAttribute("color", "#949494");

  writer.AddStyleAttribute("font-weight", "bold");

  writer.AddStyleAttribute("background-color", this.BarBackGroundColor);

  base.AddAttributesToRender(writer);

  }

  #endregion

  也不用说,大家一看都明白。

  实现ICallbackEventHandler

  

复制代码 代码如下:

  #region ICallbackEventHandler 成员

  public string GetCallbackResult()

  {

  StringBuilder sb=new StringBuilder ();

  StringWriter sw=new StringWriter (sb);

  getRpt().RenderControl(new HtmlTextWriter(sw));

  return this.GetContents() + "[_]" + sb.ToString();

  }

  public void RaiseCallbackEvent(string eventArgument)

  {

  int pageindex = int.Parse(eventArgument);

  this._CurrentIndex = pageindex;

  BindData();

  }

  #endregion

  回调时先执行RaiseCallbackEvent,所以CurrentIndex改变了, BindData()执行了!!!!

  返回时时执行GetCallbackResult,string用"[_]"分开,对应上面注册的AjaxPagerCallBack js方法中的var parts =returnData.split('[_]');

  OK!简单的Ajax分页就这样简单的完成了!!!

  Northwind Orders表调用如下:

  页面中Repeater包含在<div id="AjaxData"></div>中

  代码

  

复制代码 代码如下:

  private void BindPage(string content)

  {

  SinoHelper.PageInfo info = new SinoHelper.PageInfo();

  info.PageSize = 5;

  info.RepeaterUniqueID = rpt.UniqueID;

  info.TableName = "Orders";

  info.Fields = "OrderID,CustomerID,ShipCity";

  info.IdentityField = "OrderID";

  info.Content = content;

  AjaxPager1.Info = info;

  AjaxPager1.BindData();

  }

  附下载:

  asp.net无刷新分页