首 页 | 新 闻 | 技术中心 | 第二书店 | 《程序员》 | 《开发高手》 | 社 区 | 黄 页 | 人 才
移 动专 题SUNIBM微 软微 创精 华Donews人 邮
我的技术中心 
我的分类 我的文档
全部文章 发表文章
专栏管理 使用说明



 RSS 订阅 
最新文档列表
Windows/.NET
.NET  (rss)    
Visual C++  (rss)    
Delphi  (rss)    
Visual Basic  (rss)    
ASP  (rss)    
JavaScript  (rss)    
Java/Linux
Java  (rss)    
Perl  (rss)    
综合
其他开发语言  (rss)    
文件格式  (rss)    
企业开发
游戏开发  (rss)    
网站制作技术  (rss)    
数据库
数据库开发  (rss)    
软件工程
其他  (rss)    

积极原创作者 
tellmenow (22)
cutemouse (22)
softj (78)
iiprogram (69)
qdzx2008 (50)
goodboy1881 (14)
wangchinaking (58)
fancyhf (1)
harrymeng (41)
yjz0065 (113)
CSDN - 文档中心 - .NET 阅读:10127   评论: 4    参与评论
标题   Henry手记—Web Form中的Datagrid的自定义分页     选择自 Latitude 的 Blog
关键字   asp.net datagrid 自定义分页
出处  

         Henry手记—Web Form中的Datagrid的自定义分页

                                  韩睿  ( 05/31/2003)

 

ASP.NET带给我们很多惊喜,强大的Web Form控件自然是其中的重要部分。这其中,最受关注的当然是Datagrid。在ASP中用HTML标记语法来输出数据的方法在Datagrid数据绑定面前显得如此繁杂。但是只使用Datagrid自身的功能,还是达不到实际的工作要求。本文就是给大家演示如何提高我们的工作效率、降低服务器的负载压力。

  1. Datagrid的分页显示

当查询到的数据很多,在一屏内显示出来篇幅太长的时候,我们可以利用Datagrid的分页功能让用户通过上下页的切换来查看数据。设置方法很简单:在datagrid的属性处点击“属性生成器”,然后在“分页”栏进行如图1所示的设置,页大小的行数即决定了每页显示出几行数据记录。

 

 

                       1 分页设置

  1. 自定义导航栏

在图1的属性页中的“格式”栏中,我们可以设置“页导航”的外观样式。但是很多程序设计人员都喜欢用自己定义的导航栏,而不使用默认的上下页按钮或数字按钮(即出现123……页号的形式)。那么我们可以这样来做:

(1)       如果要保留默认的导航栏,请不用看这一小节。如果要隐藏起默认的页导航栏。就请将PageStylevisible属性设置为false。或在图1“页导航”中,不勾选“显示导航按钮”即可。

(2)       在写自定义导航栏时,主要是利用CurrentPageIndex属性来设置页:

"第一页":

DataGrid1.CurrentPageIndex = 0;

"上一页":

if (DataGrid1.CurrentPageIndex > 0)

DataGrid1.CurrentPageIndex -= 1;

"下一页":

if (DataGrid1.CurrentPageIndex < (DataGrid1.PageCount - 1))

DataGrid1.CurrentPageIndex += 1;

"最后一页":

DataGrid1.CurrentPageIndex = (DataGrid1.PageCount - 1);

(3)       需要注意的是:Web Form是一种无状态的编程方式,我们在自定义了导航栏按钮的代码后,需要再次加载Datagrid的数据源。否则将看不到页切换的效果。也就是说,我们需要在按钮的click事件中加入重新加载数据源的代码,比如我们可以将加载的代码写在如下方法SetGridSource中,在按钮Click的代码最后加入SetGridSource()这句调用代码。

private void SetGridSource()

{

SqlConnection MyConnection = new SqlConnection(YourOwnConnectionString);

string SelectCommand = "SELECT * FROM YOURTABLE";

SqlDataAdapter MyCommand = new SqlDataAdapter(SelectCommand, MyConnection);

DataSet ds = new DataSet();

MyCommand.Fill(ds, " YOURTABLE ");

DataView dv = ds.Tables["YOURTABLE "].DefaultView;

DataGrid1.DataSource = dv;

DataGrid1.DataBind();

}

或者我们可以在Page_load中写入SetGridSource里的代码,使浏览器在页切换重置时可以重新加载并绑定Datagrid的数据源。要注意的是,上述代码不能写在首次加载判断 if (!IsPostBack)语句中

(4) 在页面上我们一般需要显示总页数与当前页面这样的信息。与WinForm中的Datagrid不同的是,在WinForm中需要获取与数据相关的信息,只能从Datagrid的数据源,比如DataTable中去获得数据行数,某单元格的值等信息。被WinForm中的dataset与datagrid之间的关系弄得头晕的朋友就不用再害怕了,在WebForm中,我们只要从Datagrid中就可以直接获得这些信息了。总页数是Datagrid的PageCount属性;当前页数是CurrentPageIndex属性值+1来表示,这是由于CurrentPageIndex是从0开始计数的。

  1. 自定义分页

采用Datagrid属性生成器中的分页方式,我们都会感觉到方便的欣喜。但是,用上面所说的方法,每次页切换时,都会用SELECT * FROM YOURTABLE这样的SQl语句去提取出全部的数据,而没有任何与页有关的筛选器。这大大降低了我们Web程序的效率,也增加了服务器的负担。Datagrid提供的分页特点也变得名不副实。我们希望分页能真正的实现减少每次下载的数据量的功能,就要写代码控制住每次提取的数据量大小。

要使用自定义分页,就要将 AllowCustomPaging 属性设置为 true。然后基于 PageSize VirtualItemCount 属性的值计算要显示 DataGrid 控件中每一项所需的页数。

PageSize表示的是在 DataGrid 控件的单页上显示的项数,默认值为10

VirtualItemCount表示的是总数目。那么页数自然是VirtualItemCount/PageSize

(1)       当然是首先要知道一共有多少条数据,然后我们才好进行分配,写在Page_load里:

if (!IsPostBack)

{

StartIndex = 0;//StartIndex是int类型的公用变量

SqlConnection MyConnection = new SqlConnection(YourOwnConnectionString);

SqlCommand MyCommand = new SqlCommand("SELECT mycount = COUNT(*) FROM Table",MyConnection);

MyConnection.Open();

SqlDataReader dr = MyCommand.ExecuteReader(CommandBehavior.SingleRow);

if (dr.Read())

DataGrid1.VirtualItemCount = (int)dr["mycount"];

dr.Close();

MyConnection.Close();

SetGridSource(StartIndex, "上一页");//看看现在的形参有什么不同哦

}

注:这里说一个本文研究范围之外的知识点,就是上面dr的赋值代码中,我们用的是MyCommand.ExecuteReader(CommandBehavior.SingleRow),而大家一般用的只是MyCommand.ExecuteReader(),但请记住,如果返回记录集只有一行的话,用CommandBehavior.SingleRow进行标识可以提高应用程序的执行效率。这是因为不注明的一般情况下,MyCommand执行是使用 IRowset 接口。而注明了之后,就会利用IRow 接口(如果可用)执行绑定。其中的差别请关注笔者的后续作品。

(2)         现在的主要变化当然在重新绑定数据源的方法SetGridSource中。我们给该方法加入两个输入参数:当前的页面、发出控制(即判断用户点击的是“上一页”还是“下一页”等按钮)。下面的代码主要实现按钮型导航栏,有两个按钮“上一页”与“下一页”。“第一页”与“最后一页”的写法,请网友们自行实现。在如下示例中,column1为数据表之主键。每页有5行数据。

private void SetGridSource (int StartPosition, string GoToPage)
{
 SqlConnection MyConnection = new  SqlConnection(YourOwnConnectionString);
 SqlCommand MyCommand = null;
 switch (GoToPage)
 {
  case "上一页":
      MyCommand = new
         SqlCommand("SELECT TOP 5 * FROM Table WHERE column1 >= @ID ORDER BY column1",MyConnection);
      if (StartPosition == 0)
        MyCommand.Parameters.Add("@ID",SqlDbType.NVarChar, 10).Value = "";//这里参数10是ID字段的长度
      else
        MyCommand.Parameters.Add("@ID",SqlDbType.NVarChar,10).Value =
                ViewState[(DataGrid1.CurrentPageIndex + 1).ToString()];

break;
  case "下一页":
      MyCommand = new
         SqlCommand("SELECT TOP 5 * FROM Table WHERE column1 > @ID ORDER BY column1",MyConnection);//注意:这里用的是>,不是>=哟
      MyCommand.Parameters.Add("@ID", SqlDbType.NVarChar,10).Value = DataGrid1.Items[4].Cells[0].Text;//Items[4]表示第5行即每页显示的最后一行
      break;
 }
 MyConnection.Open();
 SqlDataReader dr = MyCommand.ExecuteReader();
 DataGrid1.DataSource = dr;
 DataGrid1.DataBind();
 dr.Close();
 MyConnection.Close();

  //用ViewState来缓存刚才访问过的那一页的第一行中的主键值
 ViewState[(DataGrid1.CurrentPageIndex + 1).ToString()]=DataGrid1.Items[0].Cells[0].Text;
}

注:如果是oracle数据库,可以在where条件中用rownum来控制上下页的条数与内容。

请在按扭的click事件里的最后调用SetGridSource方法,参数

StartPosition= DataGrid1.CurrentPageIndex *DataGrid1.PageSize;

[参考]关于Datagrid分页的更详细的内容,可以参看华中科技大学出版社出版的章立民先生所著之《用实例学ASP.NET--使用VB.NET与ADO.NET》一书

----

声明:本文版权与解释权归韩睿所有,如需转载,请保留完整的内容及此声明。

QQ: 18349592

E-Mail: henry7685@hotmail.com

     请访问本人专栏:http://www.csdn.net/develop/author/netauthor/Latitude/


相关文章
对该文的评论
cleo ( 2003-06-09)
用这个试试:http://aspx.popdc.com,相信只要不是特别大的数据量,不需要使用自定义分页。
zhucp ( 2003-06-03)
public string GetGoogleURL() 得到如下结果:
http://www.91code.com/upload/jszl/photos/20035316112544.gif


zhucp ( 2003-06-03)
using System;
using System.Data;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
namespace aspxdb
{
/// 
/// 功能 : 操作 SQL Server 数据库的 DB类, 包括执行SQL ,执入返回主键ID
/// 得到google导航条,得到第一页,下一页,上一页,最后页,
/// 得到sql 语句的执行后的结果集总数,页总数,当前包数据等
/// 作者:朱春平
/// MSN :zhucp@msn.com        QQ:6267294       EMail :zcp@chinahw.net
/// 

/// 
public class aspxdb_class
{
[DllImport("kernel32")]
private static extern int GetPrivateProfileString(string section,string key,string def,StringBuilder retVal,int size,string filePath);
[DllImport("kernel32")] 
private static extern void GetWindowsDirectory(StringBuilder WinDir,int count);


public System.Data.OleDb.OleDbConnection  OleConnection;
public System.Data.OleDb.OleDbDataAdapter OleDataAdapter;
public System.Data.OleDb.OleDbCommand  OleSelectCommand;
public System.Data.OleDb.OleDbCommand  OleInsertCommand;
public System.Data.DataSet OleDataSet;

private string ZCP_Url;
private string ZCP_QueryString;
private string ZCP_PageVName;
private string ZCP_FirstUrl,ZCP_PriorUrl,ZCP_NextUrl,ZCP_LastUrl;

private int ZCP_RecordCount;
private int ZCP_PageCount;
private int ZCP_CurrentPage;
private int ZCP_ReturnRowCount;

//取出Ini文件中的值
private string IniReadValue(string Section,string Key)
{
StringBuilder temp = new StringBuilder(255);
GetWindowsDirectory(temp,255);
string WinPath = temp.ToString() + "\\DBConnection.Config";
int i = GetPrivateProfileString(Section,Key,"",temp,255,WinPath);
return temp.ToString();
}
//构造函数
public aspxdb_class(string DBSymbol)
{
       // TODO: 在此处添加构造函数逻辑
string ConnString = IniReadValue(DBSymbol,"DBConf");

this.OleConnection = new System.Data.OleDb.OleDbConnection(ConnString); 

            this.OleDataAdapter = new System.Data.OleDb.OleDbDataAdapter();
this.OleSelectCommand = new System.Data.OleDb.OleDbCommand();
this.OleInsertCommand = new System.Data.OleDb.OleDbCommand();
this.OleDataSet = new System.Data.DataSet(); 

this.OleDataAdapter.SelectCommand = this.OleSelectCommand;
this.OleDataAdapter.InsertCommand = this.OleInsertCommand;

this.OleSelectCommand.Connection = this.OleConnection;
this.OleInsertCommand.Connection = this.OleConnection;
}
//设置连接URL参数
public void Set_BaseURL(string StrUrl, string StrPageVName, string StrQueryString)
{
    this.ZCP_Url = StrUrl;
    this.ZCP_PageVName = StrPageVName;
this.ZCP_QueryString = StrQueryString;
}
//设置参数,当前页与返回包大小
public void Set_BaseParamenter(int ReturnCount, int CurrentPage)
{
this.ZCP_ReturnRowCount = ReturnCount;
if (CurrentPage <= 0)
{
this.ZCP_CurrentPage = 1;
}else
{
this.ZCP_CurrentPage = CurrentPage;
}
}
//查询语句,一次性查询下载所有的数据
public void Query_None(string sql,string DataSetName_)
{
this.OleSelectCommand.CommandType = CommandType.Text;
this.OleSelectCommand.CommandText = sql;
this.OleConnection.Open();
this.OleSelectCommand.ExecuteNonQuery(); 
this.OleConnection.Close();
if (DataSetName_.Equals(""))
{
this.OleDataAdapter.Fill(this.OleDataSet);
}
else
{
this.OleDataAdapter.Fill(this.OleDataSet,DataSetName_);  
}

}
//查询语句,下载ReturnCount条记录(起到分页)
public void Query_Page(string StrFields, string StrTables, string StrWhere, string StrOrder, string StrMasterKey,string DataSetName_)
{
string sql ,SQLWhere,SQLXWhere;
int RowPosition;
            
//分析SQL Where 语句
if (!StrWhere.Trim().Equals(""))
{
SQLWhere = " WHERE " + StrWhere;
SQLXWhere= " AND " + StrWhere;
}else
{
SQLWhere = "";
SQLXWhere= "";
}
sql = "SELECT COUNT(*) AS RCount FROM " + StrTables + SQLWhere;
this.OleSelectCommand.CommandType = CommandType.Text;
this.OleSelectCommand.CommandText = sql;
this.OleConnection.Open(); 
this.ZCP_RecordCount = Convert.ToInt32(this.OleSelectCommand.ExecuteScalar()); 
this.OleConnection.Close(); 
//计算总页数
this.ZCP_PageCount =(int)System.Math.Ceiling((double)this.ZCP_RecordCount / this.ZCP_ReturnRowCount);
//Get RowPosition
if (this.ZCP_CurrentPage <= 1)
{
RowPosition = 0;
}
else
{
RowPosition = this.ZCP_ReturnRowCount * (this.ZCP_CurrentPage - 1);
}
if (this.ZCP_CurrentPage >= this.ZCP_PageCount)
{
RowPosition = this.ZCP_ReturnRowCount * (this.ZCP_CurrentPage - 1);
}
RowPosition = this.ZCP_ReturnRowCount * (this.ZCP_CurrentPage - 1) ;
if (RowPosition < 0)RowPosition = 0;


//Get CurrentPage Data Package
sql = "SELECT TOP " + this.ZCP_ReturnRowCount.ToString() + " " + StrFields + " FROM ";
sql = sql + StrTables + " WHERE " + StrMasterKey + " NOT IN (SELECT TOP " + RowPosition.ToString();
sql = sql + " " + StrMasterKey + " FROM " + StrTables + SQLWhere + " " + StrOrder;
sql = sql + ") " + SQLXWhere + " " + StrOrder;

this.OleSelectCommand.CommandText = sql;
this.OleConnection.Open(); 
this.OleSelectCommand.ExecuteNonQuery();
this.OleConnection.Close(); 
if (DataSetName_.Equals(""))
{
    this.OleDataAdapter.Fill(this.OleDataSet);
}else
{
    this.OleDataAdapter.Fill(this.OleDataSet,DataSetName_);  
}
//--------------------- Calculate URL String --------------------------------
//Get First Url
this.ZCP_FirstUrl = ZCP_Url + "?" + ZCP_PageVName + "=1" + ZCP_QueryString;
//Get Last Url
this.ZCP_LastUrl  = ZCP_Url + "?" + ZCP_PageVName + "=" + ZCP_PageCount.ToString() + ZCP_QueryString;
//Get Prior Url
if ((this.ZCP_CurrentPage - 1) > 0)
{
this.ZCP_PriorUrl = ZCP_Url + "?" + ZCP_PageVName + "=" + Convert.ToString((ZCP_CurrentPage-1)) + ZCP_QueryString;
}else

this.ZCP_PriorUrl = this.ZCP_FirstUrl;
    }
//Get Next Url
if ((this.ZCP_CurrentPage + 1) < this.ZCP_PageCount)
{
this.ZCP_NextUrl = ZCP_Url +"?" + ZCP_PageVName + "=" + Convert.ToSingle(ZCP_CurrentPage + 1) + ZCP_QueryString;
}else
{
this.ZCP_NextUrl = this.ZCP_LastUrl;
}

}
//执行sql 语句的函数
public int Exec_SQL(string sql)
{
int icount;
this.OleInsertCommand.CommandType = CommandType.Text;
this.OleInsertCommand.CommandText = sql;
this.OleConnection.Open(); 
icount = this.OleInsertCommand.ExecuteNonQuery(); 
this.OleConnection.Close();
            return icount;            
}
//执行sql insert into 语句
public int Exec_SQL_Insert(string sql)
{
int AutoID;
this.OleInsertCommand.CommandType = CommandType.Text;
this.OleInsertCommand.CommandText = sql + " " + "SELECT @@IDENTITY  as IAutoID";
this.OleConnection.Open();
AutoID = Convert.ToInt32(this.OleInsertCommand.ExecuteScalar()); 
this.OleConnection.Close();
return AutoID;
  }
//得到记录数
public int GetRecordCount()
{
return this.ZCP_RecordCount;
}
//得到页总数
public int GetPageCount()
{
return this.ZCP_PageCount;
}
//得到第一页URL
public string GetFirstURL()
{
return this.ZCP_FirstUrl;
}
//得到上一页URL
public string GetPrevURL()
{
return this.ZCP_PriorUrl;
}
//得到下一页URL
public string GetNextURL()
{
return this.ZCP_NextUrl;
}
//得到最后页URL
public string GetLastURL()
{
return this.ZCP_LastUrl;
}
//得到GoogleURL
public string GetGoogleURL()
{
string GoogleUrls = "",JS="",tmpStr;
int i,PNumber;

if (this.ZCP_PageCount <= 1)  return "";

//Url Number degression
PNumber = this.ZCP_CurrentPage;
for(i = 1 ; i <= 5 ; i++)
{
tmpStr = "";
PNumber = PNumber - 1;
if (PNumber > 0)
{
tmpStr = tmpStr + " tmpStr = tmpStr + ZCP_Url + "?" + ZCP_PageVName + "=" + PNumber.ToString() + ZCP_QueryString;
tmpStr = tmpStr + " style=\"TEXT-DECORATION: none\">";
tmpStr = tmpStr + PNumber.ToString() + "
 ";
GoogleUrls = tmpStr + GoogleUrls;
}else
{
break;
}
}

//First URL
GoogleUrls = "9 " + GoogleUrls;


//Current URL
if (this.ZCP_CurrentPage > 0)
{
GoogleUrls = GoogleUrls + "" + ZCP_CurrentPage.ToString() + " ";
}

//Url Number increase
PNumber = this.ZCP_CurrentPage;
for(i = 1 ; i <= 5 ; i++)
{
PNumber = PNumber + 1;
if (PNumber <= this.ZCP_PageCount)
{
GoogleUrls = GoogleUrls + " GoogleUrls = GoogleUrls + ZCP_Url + "?" + ZCP_PageVName + "=" + PNumber.ToString() + ZCP_QueryString;
GoogleUrls = GoogleUrls + " style=\"TEXT-DECORATION: none\">";
GoogleUrls = GoogleUrls + PNumber.ToString() + "
 ";
}else
{
break;
}
}
// Last Url
GoogleUrls = GoogleUrls + ":";
            GoogleUrls = GoogleUrls + "";
//GoogleUrls = GoogleUrls + "";
tmpStr = ZCP_Url + "?" + ZCP_QueryString + "&" + ZCP_PageVName + "=" ;
JS = "";
JS = JS + "function Go_Url_Button_Click(){";
JS = JS + "if (document.all.TN_Pages.value == \"\") return;";
JS = JS + "if (document.all.TN_Pages.value>" + ZCP_PageCount.ToString() + ") return;";
JS = JS + "var i,j,strTemp=\"0123456789\";";
JS = JS + "var NUM = document.all.TN_Pages.value;";
JS = JS + "if ( NUM.length== 0)return;";
JS = JS + "for (i=0;i JS = JS + "j=strTemp.indexOf(NUM.charAt(i));";
JS = JS + "if (j==-1) return;}";
JS = JS + "var tmp_url =\"" + tmpStr + "\" +  document.all.TN_Pages.value;";
JS = JS + "window.location.href = tmp_url;}";
JS = JS + "";
            GoogleUrls = GoogleUrls + JS;
  return GoogleUrls;
}
//到得当前包
public System.Data.DataSet GetDataSet()
{
return this.OleDataSet;
}

public void DestroySelf()
{
try
{
    this.OleDataSet.Clear();
    this.OleConnection.Close();
}
catch(System.Data.OleDb.OleDbException)
{
  ; 
}
}

}
}
zhucp ( 2003-06-03)
如果,是sql server ,下面我的方法不知怎样