WinForms DataGrid Pagination in .NET 1.1 (with highlighting)

(download at the end of this post)

Problem

Believe it or not, there are still poor souls out there stuck with antiquated equipment. In the previous post on highlighting DataGrid rows, I recounted a situation in which I found myself needing to implement myself a feature in .NET 1.1 that is easy in .NET 2.0 or above.

To summarize, instead of handling an event, I had to go down a much pricklier path:

  • Via polymorphism and event-handling dexterity, enable arbitrary highlighting of rows in a DataGrid.
  • Force the colored rows to behave when sorting on any column.
  • Mourn the fact that for relatively large DataSets, the re-coloring of rows after a sort is a performance problem, the solution of which is to implement paging.

To the best of my knowledge, paging a System.Windows.Forms DataGrid is not supported in any version of .NET.

Solution

When I started thinking about this post on Monday, I was just going to outline possible solutions:

  • Out-of-memory paging: hit your data source as the user pages through data, only loading pages that need to be loaded for viewing
  • Out-of-memory paging with cache: same as above except load the current page, previous page, and next page
  • In-memory paging: load entire DataSet and page in memory

Upon first encountering the problem while on The Project, my first instinct was either of the first two options. While considering the solution on Monday, this did not change.

But I have since become much more wise and lazy since The Project ended, and honestly, I don’t like writing so much code, because bugs will surely follow. The first two solutions are not ideal because they involve knowing what your data source is and most likely changing to accommodate extra parameters to indicate how many records to fetch for a given query.

In The Project’s case, SQL Server inexplicably does not allow you to use a stored procedure in a FROM clause. So to do any out-of-memory paging would require changes to the s-procs.

Then, to maintain proper layering, report services and repositories would have to change for the same reason. Add caching to the mix and this is a minor headache.

Finally, out-of-memory paging would be good for performance problems related to the size of the DataSet. No such problem existed, so tackling it at this point would be over-engineering.

So, I settled on in-memory paging. At first I was only going to outline the solution with UML and a half-hearted code example. As usual, I wrote the example first. Then I looked deep into its eyes. And just like that episode of Seinfeld where Jerry shaves his chest:

Jerry: I did something stupid.

Kramer: What did you do?

Jerry: Well I was shaving. And I noticed an asymmetry in my chest hair and I was trying to even it out. Next thing I knew, (high pitched voice) Gone.

one thing led to another, half a day of coding and debugging led to two days, and at the end of this post you can download a WinForms DataGrid Pagination demo.


(red is the highlighting color here)

Since you can download the VS project in all its glory, I will only list the PaginatedDataGrid interface:

namespace System.Windows.Forms
{
public interface PaginatedDataGrid
{
uint pageSize
{
set;
}

void moveToNextPage();
void moveToPrevPage();
void moveToFirstPage();
void moveToLastPage();
bool canMoveBack();
bool canMoveForward();
String getCurrentPaginationInfo();
void sort(int col, bool descending);
}
}

This is supposed to be self-explanatory. The only thing that would need to be explained is that the PaginatedDataGrid is a wrapper around an existing DataGrid, and that DataGrid must use a DataSet as its DataSource. Hence, the download contains only one implementation of this interface. If I ever wanted this code up on CodeProject, I’d implement the remaining five.

PaginatedDataGrid is a bit like the Decorator pattern in that it can be turned on and off at run-time, save the exact inheritance structure of the actual pattern.

Also, you’ll notice this example in C# instead of the usual VB. I have started re-implementing the core of The Project in my spare time so I can fix all of the ridiculous design mistakes I made, practice TDD, and learn C#.

Usage

I wrote this example in .NET 3.5. It is ready to run, except you need to provide your own DataSet, however you wish to do so. I did it through SQL Server and I left the boilerplate code for that route in the demo if you choose to do so.

Checking the “Pagination on” checkbox will turn the feature on and off so you can see the performance problem I was facing. You can also choose your own page size by entering a valid positive integer (I didn’t sanity-check this field so be nice) and tabbing off the textbox.

Comments

Here is a sampling of the interesting bugs I had to destroy:

  • When moving from page to page, sometimes page P’s first row, if to be highlighted, wouldn’t be highlighted until you either moved to page P+1 or highlighted the rows twice.
  • Getting a truly “deep copy” of the rows of the initial DataSet proved to be more of a challenge than it should’ve been.
  • Adding those rows back to the DataTable of the DataSet had to be accomplished with a new object array because you can’t create a new DataRow and can’t add the existing one because of an ArgumentException that I didn’t feel like dealing with.
  • Sorting on a page would only sort that page, when it should sort the entire DataSet and then reload the page you’re on for that DataSet.

Download

ZIP file can be downloaded here. Any feedback is much appreciated.

About these ads

8 Responses to “WinForms DataGrid Pagination in .NET 1.1 (with highlighting)”

  1. I always believed that implementation of pagination is exclusively meant for winforms, coz everytime i did a search for pagination, somehow i ended up with examples showing pagination for webpages and reasons why it exist. And then i found your article which makes great sense. I am awaiting my license for .net 3.5 until then, i thought of asking you something.

    If i try opening your solution file using .net 2005 it just doesnt respond. Infact, nothing happens. Is there some way i can successfully run your piece of code using .net 2005? Least i can think of is, making a new project within .net 2005 and adding each and every class file individually – but m not sure it would work or not since there is a chance you might be using some .net API which is exclusively available in 3.5.

    Please suggest.

    Thanks,
    bhavin

  2. Hey Bhavin. I did not regression-test this solution with previous versions of .NET. I would go ahead and create a 2005 solution and add the class files one by one. I don’t think I called any functions that are new or different between 2005 and 2008.

    What might be different is use of generics. I know they were introduced in 2.0, but how widespread that introduction is I’m not sure.

  3. Pretty good post. I just stumbled upon your blog and wanted to say that I have really enjoyed reading your blog posts. Any way I’ll be subscribing to your feed and I hope you post again soon. . . .

  4. HI

    I get some error for download the code.
    I want code for datagrid paging.
    Please send me the code

  5. Again, I will try to find some time to find that code and re-post it somewhere. You can help me out by suggesting some free hosting.

  6. Link updated… finally!

  7. I don’t like writing so much code, because bugs will surely follow. The first two solutions are not ideal because they involve knowing what your data source is.

  8. do you have any other link for download

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: