datagrid自定义分页篇

datagrid自定义分页是datagrid的一个重要的功能,datagrid自定义分页主要用于数据源较大时。因为数据源大(记录多),加载时间长,反应慢,耗服务器的资源。而且每显示一页就要重新加载所有的数据。而如果我们用自定义分页,则每一次只加载一页的记录,也就是只加载我们要显示的记录。这样加载数据时间短,反应快,节约服务器的资源。在做项目的过程中,我们也经常需要用到自定义功能。今天我们就说说怎样自定义分页。
   先看看datagrid的自定义分页的原理,它主要依据两个主要属性,第一个就是VirtualItemCount属性,它表示datagrid一共要显示多少条记录,它就是的作用是用于生成pager(分页导航行),通过结合另外两个属性pagesize和PageButtonCount,datagrid就知道要分成多少页及当前要显示多少个分页按钮,我们不难得到总共要显示的总页数=(VirtualItemCount+pagesize-1)/pagesize;如要总页数<PageButtonCount,则显示”总页数”个按钮;如果总页数>PageButtonCount,则显示PageButtonCount个按钮,当然到了最后一页就只显示VirtualItemCount% pagesize(总记录条数除以每页显示记录的余数)个按钮。另一个重要的属性就是datasource(数据源),自定义分页的一个重要的特点是显示数据源中所有的记录,如果数据源中有一条记录,则显示一条记录;如果数据源中有一万条记录,则它会显示一万条记录,可能你的机子就慢了 : )。所以自定义分页最重要的一点是如何设置或获取数据源了。
   接下来,我们说说自定义分页的主要步骤:
1. 设置datagrid的VirtualItemCount属性;
2. 获取datagrid的datasource(数据源);
3. 绑定数据到datagrid;
4. 设置新页的页码(datagrid.currentpageindex属性)。
重复上述2,3,4步。

  下面我们以一个例子来讲解datagrid 的自定义过程。
  例子要求机子装有ms sql server 7.0 或 2000,当然还要能运行asp.net页了(废话)。
我们先来写一个通用的自定义存储过程,用于分页,返回某页的要显示的记录集,总的记录条数(作为输出参数):
CREATE PROCEDURE up_custompage @vc_order_column_name varchar(100),@vc_select_column_list varchar(100),
@vc_select_table_list varchar(100),@vc_condition varchar(100),@page_size int,@current_page int,@total1 int output
/*
 (
  @vc_order_column_name :表要排序列的列名,只能按一列排序,而且该列必须得在输出列表中;
  @vc_select_column_list :返回列的列名列表,可以为多个列;
  @vc_select_table_list:要查询表的表名及关联表的连接;
  @vc_condition:查询条件的字符串,必须要有查询列,否则会抛出异常;
  @page_size:每页显示记录的条数;
  @current_page:当前页的页码;
  @total1:所有符合条件的记录的总数。
 )
*/
AS
--声明要用到的变量,@temp1是正常的分页语句字符串,@temp2是最后一页的分页语句字符串,@page_total表一共有几页,@last_page
--是最后一页的页码
declare @temp1 varchar(500),@temp2 nvarchar(500),@page_total int,@last_page int
--构造获得总页的数的检索语句
set @temp2=N'select @total2=count(*) from ' + @vc_select_table_list + ' where ' + @vc_condition
--执行检索语句,取得总的记录条数
exec sp_executesql @temp2,N' @total2 int output ',@total1 output

/*构造分页检索语句,基本原理是先取出@page_size*@current_page条记录,相当于是取出当前页及当前页前面的所有页面的记录,然后取出当前面所要显示的记录,也就是反序排序后取前@page_size条记录;最后再反序排序(因为前面的顺序被反排过一次,现在再反排一次,正好是我们要的顺序),最后执行,返回结果集。
*/
if @total1>0
begin
set @page_total=(@total1+@page_size-1)/@page_size
--如果当前页不是最后一页
if @current_page<@page_total
set @temp1='select top ' + cast(@page_size as varchar(4)) + ' * from
(select top ' + cast(@page_size as varchar(4))  + ' ' + @vc_select_column_list + ' from ' + @vc_select_table_list +' where ' + @vc_order_column_name
+ ' in (select top ' + cast(@page_size*@current_page as varchar(10)) + ' ' + @vc_order_column_name + ' from ' +
@vc_select_table_list + ' where '+ @vc_condition  + ' order by ' +
@vc_order_column_name + ') order by ' + @vc_order_column_name  + ' DESC) as temp1 order by ' + @vc_order_column_name
else
--最后一页只返回分页后的最后几条记录,也就是@total1%@page_size条记录
begin
set @last_page=@total1%@page_size
set @temp1='select top ' + cast(@last_page as varchar(4)) + ' * from
(select top ' + cast(@last_page as varchar(4))  + ' ' + @vc_select_column_list + ' from ' + @vc_select_table_list +' where ' + @vc_order_column_name
+ ' in (select top ' + cast(@total1 as varchar(10)) + ' ' + @vc_order_column_name + ' from ' +
@vc_select_table_list + ' where '+ @vc_condition  + ' order by ' +
@vc_order_column_name + ') order by ' + @vc_order_column_name  + ' DESC) as temp1 order by ' + @vc_order_column_name
end
--执行检索
exec(@temp1)
end
else
return
然后在新建一个aspx页面,代码如下:
<%@ Page language="c#" Codebehind="custompage.aspx.cs" AutoEventWireup="false" Inherits="cyc_test.custompage" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
 <HEAD>
  <title>custompage</title>
  <meta content="Microsoft Visual Studio 7.0" name="GENERATOR">
  <meta content="C#" name="CODE_LANGUAGE">
  <meta content="JavaScript" name="vs_defaultClientScript">
  <meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">
  <style>A { BEHAVIOR: url(MouseOver.htc) }
 HR { COLOR: black; HEIGHT: 2px }
 .StdText { FONT-WEIGHT: bold; FONT-SIZE: 9pt; FONT-FAMILY: verdana }
 .StdTextBox { BORDER-RIGHT: black 1px solid; BORDER-TOP: black 1px solid; FONT-SIZE: 9pt; FILTER: progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2, Color='gray', Positive='true'); BORDER-LEFT: black 1px solid; BORDER-BOTTOM: black 1px solid; FONT-FAMILY: verdana }
 .Shadow { FILTER: progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2, Color='gray', Positive='true') }
  </style>
 </HEAD>
 <body style="FONT-FAMILY: arial" bgColor="ivory" MS_POSITIONING="GridLayout">
  <form id="custompage" method="post" runat="server">
   <h2>项目总结之datagrid自定义分页篇
   </h2>
   <asp:label id="Label1" runat="server" font-bold="true" cssclass="StdText">当前路径: </asp:label><asp:label id="lblURL" style="COLOR: blue" runat="server" cssclass="StdText"></asp:label>
   <!-- Query --><br/>
   <asp:label id="Label2" runat="server" cssclass="stdtext" Text="查询语句:"></asp:label>
<asp:textbox id="Textbox1" runat="server" cssclass="stdtextbox" text="SELECT employeeid, firstname, lastname,title FROM Employees where employeeid>0 order by employeeid" width="765px" Enabled="false"></asp:textbox>
   <hr>
   <!-- Show the information -->
<asp:datagrid id="grid" runat="server" OnPageIndexChanged="PageIndexChanged" AllowCustomPaging="True" AllowPaging="True" PageSize="5" BorderWidth="1" BorderColor="black" BorderStyle="solid" BackColor="White" CssClass="Shadow" GridLines="vertical" CellSpacing="0" CellPadding="2" Font-Names="Verdana" Font-Size="Smaller">
    <PagerStyle Font-Bold="true" Mode="NumericPages" BackColor="palegreen" />
    <AlternatingItemStyle BackColor="#eeeeee" />
    <ItemStyle BackColor="White" />
    <HeaderStyle Font-Bold="True" ForeColor="White" BackColor="Navy" />
   </asp:datagrid></form>
 </body>
</HTML>

再写后台的源代码:
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;

namespace cyc_test
{
 /// <summary>
 /// custompage 的摘要说明。
 /// </summary>
 public class custompage : System.Web.UI.Page
 {
  protected System.Web.UI.WebControls.Label Label1;
  protected System.Web.UI.WebControls.Label lblURL;
  protected System.Web.UI.WebControls.Label Label2;
  protected System.Web.UI.WebControls.TextBox Textbox1;
  protected System.Web.UI.WebControls.DataGrid grid;
 
  private void Page_Load(object sender, System.EventArgs e)
  {
   // 第一次加载页时,初始化
   if (!Page.IsPostBack)
   {
    lblURL.Text = Request.Url + "<hr>"; 
    createdatasource(1);
   }
  }

  //绑定datagrid的函数
protected void createdatasource(int current_page)
  {
   string str_table_name,str_column_list,str_order_column,str_condition;
   //查询的表名
   str_table_name="employees";
   //返回的列名列表
   str_column_list="employeeid,firstname,lastname,title";
   //排序列的列名
   str_order_column="employeeid";
   //查询的表件
   str_condition="employeeid>0";
   string strConn = "DATABASE=Northwind;SERVER=localhost;UID=sa;PWD=;";
   SqlConnection conn = new SqlConnection(strConn);
   //声明执行存储过程的SqlCommand
   SqlCommand scd_sel=new SqlCommand("up_custompage",conn);
   scd_sel.CommandType=CommandType.StoredProcedure;
   //给存储过程的参数赋值
   SqlParameter sp_temp;
   sp_temp=scd_sel.Parameters.Add("@vc_order_column_name",SqlDbType.VarChar,100);
   sp_temp.Direction=ParameterDirection.Input;
   sp_temp.Value=str_order_column;
   sp_temp=scd_sel.Parameters.Add("@vc_select_column_list",SqlDbType.VarChar,100);
   sp_temp.Direction=ParameterDirection.Input;
   sp_temp.Value=str_column_list;
   sp_temp=scd_sel.Parameters.Add("@vc_select_table_list",SqlDbType.VarChar,100);
   sp_temp.Direction=ParameterDirection.Input;
   sp_temp.Value=str_table_name;
   sp_temp=scd_sel.Parameters.Add("@vc_condition",SqlDbType.VarChar,100);
   sp_temp.Direction=ParameterDirection.Input;
   sp_temp.Value=str_condition;
   sp_temp=scd_sel.Parameters.Add("@page_size",SqlDbType.Int);
   sp_temp.Direction=ParameterDirection.Input;
   sp_temp.Value=grid.PageSize;
   sp_temp=scd_sel.Parameters.Add("@current_page",SqlDbType.Int);
   sp_temp.Direction=ParameterDirection.Input;
   sp_temp.Value=current_page;
   sp_temp=scd_sel.Parameters.Add("@total1",SqlDbType.Int);
   sp_temp.Direction=ParameterDirection.Output;
   
   //执行存储过程
   SqlDataAdapter sda=new SqlDataAdapter();
   sda.SelectCommand=scd_sel;
   if (conn.State==ConnectionState.Closed)
    conn.Open();
   DataSet ds=new DataSet();
   sda.Fill(ds,"tb1");  
   conn.Close();
   //设置VirtualItemCount属性
   grid.VirtualItemCount=(int)scd_sel.Parameters["@total1"].Value;
   //绑定数据源
   grid.DataSource=ds.Tables["tb1"].DefaultView;
   grid.DataBind();
  }

  #region Web Form Designer generated code
  override protected void OnInit(EventArgs e)
  {
   //
   // CODEGEN:该调用是 ASP.NET Web 窗体设计器所必需的。
   //
   InitializeComponent();
   base.OnInit(e);
  }
  
  /// <summary>
  /// 设计器支持所需的方法 - 不要使用代码编辑器修改
  /// 此方法的内容。
  /// </summary>
  private void InitializeComponent()
  {   
   this.grid.ItemCreated += new System.Web.UI.WebControls.DataGridItemEventHandler(this.grid_ItemCreated);
   this.grid.PageIndexChanged += new System.Web.UI.WebControls.DataGridPageChangedEventHandler(this.PageIndexChanged);
   this.Load += new System.EventHandler(this.Page_Load);

  }
  #endregion
  //datagrid的ItemCreated事件,用于定制分页导航行
  private void grid_ItemCreated(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
  {
   
   ListItemType elemType = e.Item.ItemType;
   //定制分页导航行,样式为[1] [2] 第 3 页 [4]
   if (elemType == ListItemType.Pager)
   {
    
    TableCell pager = (TableCell) e.Item.Controls[0];
   
    for (int i=0; i<pager.Controls.Count; i+=2)
    {
     Object o = pager.Controls[i];
     if (o is LinkButton)
     {
      LinkButton h = (LinkButton) o;
      h.Text = "[ " + h.Text + " ]";
     }
     else
     {
      Label l = (Label) o;
      l.Text = "第" + l.Text + “页”;
     }
    }
   }
  } 
  //页选中(分页)事件
  public void PageIndexChanged(object source, System.Web.UI.WebControls.DataGridPageChangedEventArgs e)
  {
   grid.CurrentPageIndex = e.NewPageIndex;
   //页码值是从零开始的,所以要加一
   createdatasource(grid.CurrentPageIndex+1);
  }
 }
}

     要运行上面的示例,请按上面的顺序先创建存储过程,再写页面的代码,最后是源代码。示例参考了《构建Web解决方案---应用ASP.NET和ADO.NET》中的分页思路。在本机调试通过。大家只要明白存储过程分页的思想就可以了。如果大家有更好的方案,请提出来,也许你的更好!
   这一段时间又开始了新的项目,所以这篇文章写得比较仓促,可能有些地方讲得不明白,大家可以提问和讨论。希望对大家有所帮助。

  语句的整体架构
 


select top 每页显示的记录条数 * from
(
 select top 每页显示的记录条数 要显示的字段列表 from 要查询的表的列表(包括连接语句)where 排序字段 in
  (
   select top 每页显示的记录条数 排序字段 from 要查询的表的列表(包括连接语句)where order by 排序字段
   )
 order by 排序字段 desc
)
as temp1
order by 排序字段

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值