OK, because I think all you clods have the same problem as a clod like me, the following post can really be helpful, I think.
DataGrid in ASP.NET 1.x, and its
VirtualItemCount property? If you wanted the
DataGrid to display a custom pager row, you just had to set
true, bind a data source to it, and supply a number to the
VirtualItemCount property. Et voilà: the pager bar comes up automatically! Magic!
With ASP.NET 2.0, a new kid was in town: the
GridView. Great stuff !! But, wait a minute, it isn't that easy to display a custom pager row! I looked and looked and searched and read quite some stuff, and finally, I came up with the following solution. Now, I could very well keep this just to myself, but since I'm such a nice person, I'll share it with all you clowns..
Suppose that you have the following situation:
- You have a
GridView, and you want only 10 records to display at a time.
- You have a table which contains 30,000 records.
- You don't want to use the default paging of the
GridView, because this will retrieve all 30,000 records at every round trip.
- You have figured out a way to retrieve only 10 records at a time. (I'm not going into the details of this, maybe in a later post, I found some great stuff to do just that!)
The only thing you need is to have the
GridView display a pager row. And there, you're stuck. Because the
GridView does not have a
VirtualItemCount property, it only has a
PageCount property, but that's read only!
A solution could be to do all the work declaratively at design time. In fact, all the tutorials and posts that you'll read show you how to do this declaratively, with the help of a
ObjectDataSource and a
TableAdapter. But that is at design time!
What if you need to bind the
GridView at run-time, i.e. programmatically? That's where the real problem lies!
In order to solve this problem, you have to know two things:
ObjectDataSource (=ODS) needs to have the name of a class that will handle the data requests. When you do this by declaration, it's the
TableAdapter that takes care of that. So, part of the solution is to create our own
- On the other hand, the ODS at run-time creates an instance of that class with a parameterless constructor. You can shout "Yikes!" twice here: first, because the data-handling object can not be instantiated (constructed) with any parameters, and second, it can not be accessed because it's shielded in the ODS.
So, how can you feed your precious 10-record table to that data-object? Well, you can't...
You do the following things:
- Create your own
TableAdapter that takes care of providing the data. Don't worry, if you're only interested in displaying records, it's done in a snap.
- Create an event-handler that takes control over what kind of datasource object is created and handed over to the ODS. Again, this only takes some lines of code.
And, you are done!
OK, let's get down to it.
First, let's create our own
TableAdapter. When it's only for data-displaying, our
TableAdapter should contain only three things:
- A method to supply the data (e.g., a
DataTable) (in our example, only 10 rows)
- A method to supply the total number of rows in the table (30,000)
- A method to supply the data with two parameters: one for setting the start-row-index, and the other for setting the maximum-rows. (Actually, I'm not going to do anything with this, because I already have my
DataTable with the right records! Still, the method has to be there!)
Also, I'm going to write a constructor of this class that will take as parameters our cute little
DataTable and the total number of rows, which I'll will call "
VirtualItemCount" (to salute the earlier
This is how it could look like:
internal class MyTableAdapter
private DataTable _dt;
private int _vic;
public MyTableAdapter(DataTable dt, int vic)
_dt = dt;
_vic = vic;
public DataTable GetData()
public int VirtualItemCount()
public DataTable GetData(int startRow, int maxRows)
The next thing we'll do is create a class which will handle the creation of a
DataTable, and hand it over to another function to feed the
internal class MyGridViewFiller
private DataTable _dt;
private int _vic;
private Page _page;
private string _id;
public void CreateCuteLittleTable(Page Page, string GridViewID)
_page = Page;
_id = GridViewID
public void FillGridView()
GridView gv = (GridView)_page.FindControl(_id);
ObjectDataSource ods = new ObjectDataSource();
ods.ID = "ods" + _id;
ods.EnablePaging = gv.AllowPaging;
ods.TypeName = "MyTableAdapter";
ods.SelectMethod = "GetData";
ods.SelectCountMethod = "VirtualItemCount";
ods.StartRowIndexParameterName = "startRow";
ods.MaximumRowsParameterName = "maxRows";
ods.EnableViewState = false;
gv.DataSource = ods;
private void ods_ObjectCreating(object sender, ObjectDataSourceEventArgs e)
e.ObjectInstance = new MyTableAdapter(_dt, _vic);
If you go very slowly through the code, you will find it very simple and straightforward. And best of all: you have the
GridView display the pager row!!! Of course, the actual paging procedures are also to be written by you, but that's maybe for another post.
Important remark: If you have a cute little
DataTable of only 10 records, then also the
PageSize should be set to 10 (duh!).
Remark 2: Hmmm, I noticed that you don't give high voting points... You could leave me a comment to point out what could be better? Thanks!