ASP.NET的自定义分页

using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
namespace ControlLibs
{
 /// <summary>
 /// CustomPager 的摘要说明。
 /// </summary>
 [DefaultProperty("Text"),
 ToolboxData("<{0}:SqlPager runat=server></{0}:SqlPager>")]
 public class SqlPager : System.Web.UI.WebControls.WebControl,System.Web.UI.INamingContainer
 {
  #region 自动生成
  private string text;
 
  [Bindable(true),
  Category("Appearance"),
  DefaultValue("")]
  public string Text
  {
   get
   {
    return text;
   }

   set
   {
    text = value;
   }
  }

  /// <summary>
  /// 将此控件呈现给指定的输出参数。
  /// </summary>
  /// <param name="output"> 要写出到的 HTML 编写器 </param>
  protected override void Render(HtmlTextWriter output)
  {
   if (Site != null && Site.DesignMode)
    CreateChildControls();

   base.Render(output);
  }
  #endregion

  #region 构造函数
  public SqlPager():base()
  {
   this.CurrentPageIndex=0;
   this.PageSize=10;
   this.PageCount=-1;
   this.RecordCount=-1;
   this.SortField="";
   this.ConnString="";
   this.ControlToPaginate="";
   this.PagingMode=PageMode.Cached;
   this.CacheDuration=60;
   this.SelectCommand="";

  }
  #endregion 

  #region 重载方法
  public override void DataBind()
  {
   base.DataBind ();
   //第一步:重绘控件**************
   this.ChildControlsCreated=false;
   //第二步:合作者控件存在,是否满足条件(ListControl,BaseDataList ),selectcmd,connstr
   if(this.ControlToPaginate=="")
    return;
   this.m_ControlToPaginate=this.Page.FindControl(this.ControlToPaginate);
   if(this.m_ControlToPaginate==null)
    return;
   if(!(this.m_ControlToPaginate is ListControl || this.m_ControlToPaginate is BaseDataList))
    return;
   
   if(this.SelectCommand=="" || this.ConnString=="")
    return;

   //第三步:取出数据
   if(this.PagingMode==PageMode.Cached)
    GetAllData();
   else
    GetPageData();

   //第四步:绑定数据
   ListControl listControl=null;
   BaseDataList baseDataList=null;
   if(this.m_ControlToPaginate is ListControl)
   {
    listControl=(ListControl)this.m_ControlToPaginate;
    listControl.Items.Clear();
    listControl.DataSource=this.m_DataSource;
    listControl.DataBind();
    return;
   }
   if(this.m_ControlToPaginate is BaseDataList)
   {
     baseDataList=(BaseDataList)this.m_ControlToPaginate;
     baseDataList.DataSource=this.m_DataSource;
     baseDataList.DataBind();
    
    return;
   }

  
  }


  protected override void CreateChildControls()
  {
   // TODO:  添加 CustomPager.CreateChildControls 实现
   //   base.CreateChildControls ();
   this.Controls.Clear();
   this.ClearChildViewState();
   InitControls();
  }
  #endregion

  #region 事件处理
  private void lb_Navigater_Click(object sender, EventArgs e)
  {

   string str=((LinkButton)sender).ID;
   switch(str)
   {
    case "first":
    {
     this.CurrentPageIndex=0;
     break;
    }
    case "prev":
    {
     this.CurrentPageIndex--;
     break;
    }
    case "next":
    {
     this.CurrentPageIndex++;
     break;
    }
    case "last":
    {
     this.CurrentPageIndex=this.PageCount-1;
     break;
    }
   }
   this.DataBind();
  }
  #endregion

  #region 分页信息类
  public class PageInfo
  {
   public int pageCount;
   public int recordCountInLast;
   public int recordCount;

  }
  #endregion

  #region 枚举
  public enum PageMode
  {
   Cached,
   NoCached
  }
  #endregion
  
  #region 私有变量
  private string m_QueryPageCommandText = "SELECT * FROM " +
   "(SELECT TOP {0} * FROM " +
   "(SELECT TOP {1} * FROM ({2}) AS t0 ORDER BY {3} {4}) AS t1 " +
   "ORDER BY {3} {5}) AS t2 " +
   "ORDER BY {3}";
  private  string m_RecordCountSql="select count(*) from ({0}) as t0";
  private System.Web.UI.WebControls.PagedDataSource m_DataSource;
  private System.Web.UI.Control m_ControlToPaginate;
  private string m_CacheKeyName
  {
   get
   {
    return this.Page.Request.FilePath+"_"+this.UniqueID+"_Data";
   }
  }
  #endregion

  #region 属性

  public int CacheDuration
  {
   get
   {
    return int.Parse(this.ViewState["CacheDuration"].ToString());
   }
   set
   {
    this.ViewState["CacheDuration"]=int.Parse(value.ToString());
   }
  }
  /// <summary>
  /// 排序字段名称
  /// </summary>
  public string SortField
  {
   get
   {
    return this.ViewState["SortField"].ToString();
   }
   set
   {
    this.ViewState["SortField"]=value.ToString();
   }
  }
  public string SelectCommand
  {
   get
   {
    return this.ViewState["SelectCommand"].ToString();
   }
   set
   {
    this.ViewState["SelectCommand"]=value.ToString();
   }
  }

  public string ConnString
  {
   get
   {
    return this.ViewState["ConnString"].ToString();
   }
   set
   {
    this.ViewState["ConnString"]=value.ToString();
   }
  }
  /// <summary>
  /// 分页模式
  /// </summary>
  public PageMode PagingMode
  {
   get
   {
    return (PageMode)this.ViewState["PagingMode"];
   }
   set
   {
    this.ViewState["PagingMode"]=(PageMode)value;
   }
  }
  /// <summary>
  /// 合作者控件名称
  /// </summary>
  public string ControlToPaginate
  {
   get
   {
    return this.ViewState["ControlToPaginate"].ToString();
   }
   set
   {
    this.ViewState["ControlToPaginate"]=value.ToString();
   }
  }
  public int RecordCount
  {
   get
   {
    return int.Parse(this.ViewState["RecordCount"].ToString());
   }
   set
   {
    this.ViewState["RecordCount"]=int.Parse(value.ToString());
    
   }
  }

  public int PageSize
  {
   get
   {
    return int.Parse(this.ViewState["PageSize"].ToString());
   }
   set
   {
    this.ViewState["PageSize"]=int.Parse(value.ToString());
    
   }
  }
  public int CurrentPageIndex
  {
   get
   {
    return int.Parse(this.ViewState["CurrentPageIndex"].ToString());
   }
   set
   {
    this.ViewState["CurrentPageIndex"]=int.Parse(value.ToString());
    
   }
  }
  public int PageCount
  {
   get
   {
    return int.Parse(this.ViewState["PageCount"].ToString());
   }
   set
   {
    this.ViewState["PageCount"]=int.Parse(value.ToString());
    
   }
  }


    
  #endregion

  #region 方法
  private void InitControls()
  {
   Table tbl=new Table();
   TableRow row=new TableRow();
   tbl.Rows.Add(row);

   TableCell PrevNextCell=new TableCell();
   InitPrevNextInfo(PrevNextCell);
   row.Cells.Add(PrevNextCell);


   TableCell PageInfoCell=new TableCell();
   InitPageInfo(PageInfoCell);
   row.Cells.Add(PageInfoCell);

   this.Controls.Add(tbl);


  }

  
  private void GetAllData()
  {
   //从缓存中取数据
   DataTable tbl;
   tbl=(DataTable)this.Page.Cache[this.m_CacheKeyName];
   if(tbl==null)
   {

    tbl=new DataTable();
    this.AdjustSelectCommand(true);
    SqlConnection conn=new SqlConnection(this.ConnString);
    SqlCommand cmd=conn.CreateCommand();
    cmd.CommandText=this.SelectCommand;
    SqlDataAdapter da=new SqlDataAdapter();
    da.SelectCommand=cmd;
    da.Fill(tbl);
    this.RecordCount=tbl.Rows.Count;
    this.Page.Cache.Insert(this.m_CacheKeyName,tbl,null,System.DateTime.Now.AddSeconds(this.CacheDuration)
     ,System.Web.Caching.Cache.NoSlidingExpiration);

   }

   if(this.m_DataSource==null)
   {
    this.m_DataSource=new PagedDataSource();
    this.m_DataSource.DataSource=tbl.DefaultView;
    this.m_DataSource.AllowPaging=true;
    this.m_DataSource.PageSize=this.PageSize;
    this.PageCount=this.m_DataSource.PageCount;
//    this.RecordCount=this.m_DataSource.VirtualCount;

    this.ValidPageIndex();
    if(this.CurrentPageIndex==-1)
    {
     this.m_DataSource=null;
     return;
    }
     
    this.m_DataSource.CurrentPageIndex=this.CurrentPageIndex;
   }
   
  }

  private void ValidPageIndex()
  {
   if(!(this.CurrentPageIndex>=0 && this.CurrentPageIndex<=this.PageCount-1))
    this.CurrentPageIndex=-1;

  }

  private void AdjustSelectCommand(bool isAddSortInfo)
  {
   string strTemp=this.SelectCommand.ToLower();
   int pos=strTemp.IndexOf(" order by ");
   if(pos>-1)
   {
    this.SelectCommand=this.SelectCommand.Substring(0,pos);
   }

   if(isAddSortInfo && this.SortField!="")
   {
    this.SelectCommand=" order by "+this.SortField;
   }

  }

  private PageInfo CalcPageInfo()
  {
            PageInfo pInfo=new PageInfo();
   

   //去掉Sort字段
   this.AdjustSelectCommand(false);

   //得到记录数量
   SqlConnection conn=new SqlConnection(this.ConnString);
   SqlCommand cmd=conn.CreateCommand();
   
   cmd.CommandText=string.Format(this.m_RecordCountSql,this.SelectCommand);
   conn.Open();
   int recordCount=(int)cmd.ExecuteScalar();
   conn.Close();
   pInfo.recordCount=recordCount;
   if(recordCount % this.PageSize>0)
   {
    pInfo.pageCount=recordCount/this.PageSize+1;
    pInfo.recordCountInLast=pInfo.recordCount % this.PageSize;
    
   }
   else
   {
    pInfo.pageCount=recordCount/this.PageSize;
       pInfo.recordCountInLast=0;
   }

   this.PageCount=pInfo.pageCount;
   this.RecordCount=pInfo.recordCount;
   

   return pInfo;
   


   
  }

  private void GetPageData()
  {
   PageInfo p=this.CalcPageInfo();
   this.ValidPageIndex();
   if(this.CurrentPageIndex==-1)
   {
    return;
   }

   SqlCommand cmd=this.PrepareCommand(p);
   if (cmd == null)
    return;
   SqlDataAdapter da = new SqlDataAdapter(cmd);
   DataTable tbl = new DataTable();
   da.Fill(tbl);

   // Configures the paged data source component
   if (this.m_DataSource == null)
    this.m_DataSource = new PagedDataSource();
//   this.m_DataSource.AllowCustomPaging = true;
//   this.m_DataSource.AllowPaging = true;
//   this.m_DataSource.CurrentPageIndex =0;
//   if(p.recordCountInLast!=0)
//    this.m_DataSource.CurrentPageIndex=p.pageCount-1;
//   this.m_DataSource.PageSize = this.PageSize;
//   this.m_DataSource.VirtualCount = p.recordCount;
   this.m_DataSource.DataSource = tbl.DefaultView; 


  }

  private SqlCommand PrepareCommand(PageInfo p)
  {
   if (SortField == "")
   {
    // Get metadata for all columns and choose either the primary key
    // or the
    string text = "SET FMTONLY ON;" + SelectCommand + ";SET FMTONLY OFF;";
    SqlDataAdapter da = new SqlDataAdapter(text, this.ConnString);
    DataTable tbl = new DataTable();
    da.MissingSchemaAction = MissingSchemaAction.AddWithKey;
    da.Fill(tbl);
    DataColumn col = null;
    if (tbl.PrimaryKey.Length >0)
     col = tbl.PrimaryKey[0];
    else
     col = tbl.Columns[0];
    SortField = col.ColumnName;
   }
   // Determines how many records are to be retrieved.
   // The last page could require less than other pages
   int recsToRetrieve = this.PageSize;
   if (CurrentPageIndex == p.pageCount-1)
    recsToRetrieve = p.recordCountInLast;

   
   string cmdText = String.Format(m_QueryPageCommandText,
    recsToRetrieve,      // {0} --> page size
    this.PageSize*(CurrentPageIndex+1), // {1} --> size * index
    this.SelectCommand,      // {2} --> base query
    this.SortField,       // {3} --> key field in the query
    "ASC",        // Default to ascending order
    "DESC");

   SqlConnection conn = new SqlConnection(this.ConnString);
   SqlCommand cmd = new SqlCommand(cmdText, conn);
   return cmd;
  }

 


  /// <summary>
  /// 初始化上下页
  /// </summary>
  /// <param name="cell"></param>
  private void InitPrevNextInfo(TableCell cell)
  {
   bool isValidPage=this.CurrentPageIndex>=0 && this.CurrentPageIndex<=this.PageCount-1;
   bool canMovePrev=this.CurrentPageIndex>0;
   bool canMoveNext=this.CurrentPageIndex<this.PageCount-1;

   LinkButton lb_First=new LinkButton();
   lb_First.ID="first";
   lb_First.Font.Name="Webdings";
   lb_First.Font.Size=FontUnit.Medium;
   lb_First.ForeColor=this.ForeColor;
   lb_First.ToolTip="首页";
   lb_First.Text="7";
   lb_First.Click+=new EventHandler(lb_Navigater_Click);
   lb_First.Enabled=isValidPage && canMovePrev;

   cell.Controls.Add(lb_First);
   cell.Controls.Add(new LiteralControl("&nbsp;"));

   LinkButton lb_Prev=new LinkButton();
   lb_Prev.ID="prev";
   lb_Prev.Font.Name="Webdings";
   lb_Prev.Font.Size=FontUnit.Medium;
   lb_Prev.ForeColor=this.ForeColor;
   lb_Prev.ToolTip="上一页";
   lb_Prev.Text="3";
   lb_Prev.Click+=new EventHandler(lb_Navigater_Click);
   lb_Prev.Enabled=isValidPage && canMovePrev;

   cell.Controls.Add(lb_Prev);
   cell.Controls.Add(new LiteralControl("&nbsp;"));


   LinkButton lb_Next=new LinkButton();
   lb_Next.ID="next";
   lb_Next.Font.Name="Webdings";
   lb_Next.Font.Size=FontUnit.Medium;
   lb_Next.ForeColor=this.ForeColor;
   lb_Next.ToolTip="下一页";
   lb_Next.Text="4";
   lb_Next.Click+=new EventHandler(lb_Navigater_Click);
   lb_Next.Enabled=isValidPage && canMoveNext;

   cell.Controls.Add(lb_Next);
   cell.Controls.Add(new LiteralControl("&nbsp;"));


   LinkButton lb_Last=new LinkButton();
   lb_Last.ID="last";
   lb_Last.Font.Name="Webdings";
   lb_Last.Font.Size=FontUnit.Medium;
   lb_Last.ForeColor=this.ForeColor;
   lb_Last.ToolTip="尾页";
   lb_Last.Text="8";
   lb_Last.Click+=new EventHandler(lb_Navigater_Click);
   lb_Last.Enabled=isValidPage && canMoveNext;

   cell.Controls.Add(lb_Last);
   cell.Controls.Add(new LiteralControl("&nbsp;"));

   
  }

  /// <summary>
  /// 初始化分页信息
  /// </summary>
  /// <param name="cell"></param>
  private void InitPageInfo(TableCell cell)
  {
   int pageIndex=this.CurrentPageIndex;
   pageIndex++;
   string str=string.Format("页次:{0}/{1} {2}个内容/页 共有{3}个内容",
    pageIndex.ToString(),this.PageCount.ToString(),this.PageSize.ToString(),this.RecordCount.ToString());
   cell.Text=str;


  }
  #endregion

  
 }
}

posted @ 2007-12-27 11:27  古道轻风  阅读(512)  评论(1编辑  收藏  举报