65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.18/5 (42投票s)

2007年1月30日

CPOL

4分钟阅读

viewsIcon

139988

如何以编程方式将 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 属性,但它是只读的!

一种解决方案是在设计时以声明方式完成所有工作。事实上,你阅读的所有教程和帖子都展示了如何通过 ObjectDataSourceTableAdapter 以声明方式做到这一点。但那是在设计时!

如果需要在运行时以编程方式绑定 GridView 呢?这才是真正的问题所在!

为了解决这个问题,你需要知道两件事

  • ObjectDataSource (=ODS) 需要一个处理数据请求的类的名称。如果你通过声明来做,那么 TableAdapter 会负责这一点。所以,解决方案的一部分是创建我们自己的 TableAdapter
  • 另一方面,ODS 在运行时会创建一个该类的实例,该类具有无参构造函数。你可以在这里大喊“哎呀!”两次:首先,因为数据处理对象不能用任何参数实例化(构造);其次,它不能被访问,因为它被隐藏在 ODS 中。

那么,你如何将你珍贵的 10 条记录的表馈送到那个数据对象呢?好吧,你不能...

除非……

你做以下事情

  1. 创建你自己的 TableAdapter 来负责提供数据。别担心,如果你只关心显示记录,那很容易做到。
  2. 创建一个事件处理程序,该处理程序可以控制创建什么类型的数据源对象并将其交给 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,那么 GridViewPageSize 也应该设置为 10( duh!)。

提示 2:嗯哼,我注意到你给的分数不高……你可以给我留个评论,指出哪些方面可以改进吗?谢谢!

© . All rights reserved.