ASP.NET 2.0 中的自定义分页和 GridView - 你会感谢我的!






3.18/5 (42投票s)
如何以编程方式将 GridView 绑定到 DataSource 并让它显示分页器。
引言
好的,因为我认为你们这些笨蛋都和我这个笨蛋一样有同样的问题,下面的帖子真的很有帮助,我认为。
还记得 ASP.NET 1.x 中的 DataGrid
及其 VirtualItemCount
属性吗?如果你想让 DataGrid
显示自定义分页行,只需将 AllowCustomPaging
设置为 true
,然后绑定数据源,并为 VirtualItemCount
属性提供一个数字。瞧:分页条会自动出现!神奇!
在 ASP.NET 2.0 中,出现了一个新东西:GridView
。很棒的东西!!但是,等等,显示自定义分页行并不那么容易!我看了又看,搜索了又搜索,读了不少东西,最后,我找到了以下解决方案。现在,我可以把这个留给自己,但因为我是一个很好的人,我会和你们所有这些傻瓜分享。
假设你有以下情况
- 你有一个
GridView
,你想一次只显示 10 条记录。 - 你有一个包含 30,000 条记录的表。
- 你不想使用
GridView
的默认分页,因为这样会在每次往返时检索所有 30,000 条记录。 - 你已经找到了一种一次只检索 10 条记录的方法。(我不会详细介绍,也许以后再写一篇帖子,我找到了很多很棒的东西来实现这一点!)
你唯一需要的就是让 GridView
显示分页行。然后,你就卡住了。因为 GridView
**没有** VirtualItemCount
属性,它只有 PageCount
属性,但它是只读的!
一种解决方案是在设计时以声明方式完成所有工作。事实上,你阅读的所有教程和帖子都展示了如何通过 ObjectDataSource
和 TableAdapter
以声明方式做到这一点。但那是在设计时!
如果需要在运行时以编程方式绑定 GridView
呢?这才是真正的问题所在!
为了解决这个问题,你需要知道两件事
ObjectDataSource
(=ODS) 需要一个处理数据请求的类的名称。如果你通过声明来做,那么TableAdapter
会负责这一点。所以,解决方案的一部分是创建我们自己的TableAdapter
!- 另一方面,ODS 在运行时会创建一个该类的实例,该类具有无参构造函数。你可以在这里大喊“哎呀!”两次:首先,因为数据处理对象不能用任何参数实例化(构造);其次,它不能被访问,因为它被隐藏在 ODS 中。
那么,你如何将你珍贵的 10 条记录的表馈送到那个数据对象呢?好吧,你不能...
除非……
你做以下事情
- 创建你自己的
TableAdapter
来负责提供数据。别担心,如果你只关心显示记录,那很容易做到。 - 创建一个事件处理程序,该处理程序可以控制创建什么类型的数据源对象并将其交给 ODS。同样,这只需要几行代码。
然后,你就**完成了**!
好的,让我们开始吧。
首先,让我们创建自己的 TableAdapter
。如果它只用于显示数据,我们的 TableAdapter
应该只包含三项内容
- 一个提供数据的方法(例如,一个
DataTable
)(在我们的例子中,只有 10 行) - 一个提供表中总行数的方法(30,000 行)
- 一个提供带有两个参数的数据的方法:一个用于设置起始行索引,另一个用于设置最大行数。(实际上,我不会对这个做任何事情,因为我已经有了包含正确记录的
DataTable
!但是,这个方法必须在那里!)
另外,我将编写一个构造函数,该构造函数将接收我们可爱的小 DataTable
和总行数作为参数,我将把它们称为“VirtualItemCount
”(以纪念之前的 DataGrid
)。
这可能是这样的
internal class MyTableAdapter
{
private DataTable _dt;
private int _vic;
//this is the constructor that takes as parameters a cute little datatable
// with the right 10 records, an an integer vic = virtualitemcount
public MyTableAdapter(DataTable dt, int vic)
{
_dt = dt;
_vic = vic;
}
//this returns the datatable (10 records)
public DataTable GetData()
{
return _dt;
}
//this returns the total number of records in the table (30.000)
public int VirtualItemCount()
{
return _vic;
}
//this also returns the datatable (10 records)
//but the ODS needs it for paging purposes
public DataTable GetData(int startRow, int maxRows)
{
return _dt;
}
}
接下来,我们将创建一个类来处理 DataTable
的创建,并将其交给另一个函数来为 GridView
提供数据。
internal class MyGridViewFiller
{
//these fields are for storing the cute little
//datatable and the virtualitemcount
private DataTable _dt;
private int _vic;
//these fields are for storing the calling page and the GridViewID
private Page _page;
private string _id;
public void CreateCuteLittleTable(Page Page, string GridViewID)
{
//here you create your cute little datatable
//and also you calculate the total number of rows
_dt = //some code to create the 10-row DataTable
_vic = //some code to calculate the total rows of the table (30.000)
//let's also store the page and the gridviewid
_page = Page;
_id = GridViewID
//call the GridView filler
FillGridView()
}
public void FillGridView()
{
//First let's make an GridView object that hold the GridView
GridView gv = (GridView)_page.FindControl(_id);
//Then create an ObjectDateSource object programmatically
ObjectDataSource ods = new ObjectDataSource();
//setting the necessary properties
//(these will interact with our TableAdapter !)
ods.ID = "ods" + _id;
//the paging of ODS depends on the paging of the GridView
ods.EnablePaging = gv.AllowPaging;
//be sure to prefix the namespace of your application
//!!! e.g. MyApp.MyTableAdapter
ods.TypeName = "MyTableAdapter";
ods.SelectMethod = "GetData";
ods.SelectCountMethod = "VirtualItemCount";
ods.StartRowIndexParameterName = "startRow";
ods.MaximumRowsParameterName = "maxRows";
ods.EnableViewState = false;
//HERE IS THE TRICK !!!
//In stead of calling the parameterless
//constructor of our TableAdapter, I'm going
//to hook up on the ods.ObjectCreating event
//to supply my own TableAdapter (WITH constructor parameters)
//the following line is the "hook up" declaration
ods.ObjectCreating +=
new ObjectDataSourceObjectEventHandler(ods_ObjectCreating);
//this means that at the object creating event, the CLR is going
//to jump to my event handler (ods_ObjectCreating)
//after that, we only need to bind the ODS to the GridView
gv.DataSource = ods;
gv.DataBind();
// AND THAT's ALL FOLKS !!!
}
//this is the ObjectCreating event handler
private void ods_ObjectCreating(object sender, ObjectDataSourceEventArgs e)
{
//calling a "parametered" constructor of my own
//TableAdapter and passing it to the ObjectInstance property
e.ObjectInstance = new MyTableAdapter(_dt, _vic);
//and that'all there's to it !!
}
}
如果你非常缓慢地浏览代码,你会发现它非常简单明了。最重要的是:你让 GridView
显示了分页行!!!当然,实际的分页过程也需要你自己编写,但这也许是另一篇文章的主题。
祝您好运!
重要提示:如果你有一个只有 10 条记录的可爱小 DataTable
,那么 GridView
的 PageSize
也应该设置为 10( duh!)。
提示 2:嗯哼,我注意到你给的分数不高……你可以给我留个评论,指出哪些方面可以改进吗?谢谢!