Click here to Skip to main content
15,891,375 members
Articles / Desktop Programming / Windows Forms
Article

Paging in DataGridView using VScrollbar

Rate me:
Please Sign up or sign in to vote.
3.27/5 (5 votes)
6 Nov 2007CPOL3 min read 85.9K   2.4K   41   10
Enable paging in a DataGridView on scrolling
Screenshot - Image.jpg

Introduction

This article provides a way to programmatically implement paging in a Windows Datagrid.

Background

Microsoft DataGridView control in Framework 2.0 does not offer an inbuilt paging functionality so as to accommodate real time loading of data from an underlying data source for handling larger data. As an example, when one has to load larger sets of data; say from a text file using OLEDB text driver.

There are certain options to manually implement paging in a DataGridViewControl; one conventional and rather easy approach is to user "button controls" to navigate back and forth into the data source. On the other hand, a little difficult approach is to implement paging on the scroll bar.

The only hurdle in this implementation is that the default Vertical Scroll Bar in DataGridView control is not that flexible to handle all the matter. For this reason, a Scroll Bar control can be best used for such an implementation. The default vertical scroll bar of the DataGridView control does not offer much customization like customizing larger and smaller change.

The following article describes how to implement paging in DataGridView control with the help of a separate Scroll Bar Control.

Using the Code

Before we look at the code, do the following:

  • Create a new C# Windows application with Visual Studio 2005
  • Drag & Drop a DatagridView control on to the Windows Form
  • Drag & Drop VScrollBar control on to the form

Now that we have done this, let's look at the code.

Reading from File

We can query the text file in the same way as we query in SQL DB or any other if we use ODBC or OleDb data adapters. Here I am using Oledb data adapter to query from a text file, so for that, at first we need a connection string:

C#
System.Reflection.Assembly a = System.Reflection.Assembly.GetEntryAssembly();
baseDir = System.IO.Path.GetDirectoryName(a.Location);
string strConneStringOLeDb = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=";
strConneStringOLeDb += baseDir+";Extended Properties='text;HDR=Yes;";
strConneStringOLeDb += "FMT=Delimited';"; 

For more information on Connection strings, see this link.

The next step is to read data from the file. For this purpose, one has to place a schema.ini file with the file from which you want to load data. The code to write a schema file is as follows:

C#
private void writeSchema()
 {
    try
     {
        FileStream fsOutput =
             new FileStream(baseDir + "\\schema.ini",
                 FileMode.Create, FileAccess.Write);
        StreamWriter srOutput = new StreamWriter(fsOutput);
        string s1, s2, s3, s4, s5;
        s1 = "[" + fileName + "]";
        s2 = "ColNameHeader=True";
        s3 = "Format=TabDelimited";
        s4 = "MaxScanRows=25";
        s5 = "CharacterSet=OEM";
        srOutput.WriteLine(s1.ToString() + '\n' + s2.ToString() +'\n' +
       s3.ToString() + '\n' +s4.ToString() + '\n' + s5.ToString());
        srOutput.Close();
        fsOutput.Close();
      }
      catch (Exception ex)
      {
          MessageBox.Show(ex.Message);
      }
  }

Now to read data from the file (not the complete file but a chunk of data) and load it in the dataset:

C#
private void LoadFromFile()
 {
    try
     {
        writeSchema();
           
        //Open the connection 
        if(conn.State == ConnectionState.Closed)
            conn.Open();

        //Fetch records from CSV
        //Count the number of lines to set the total pages      
        string sqlScalar = "Select Count(*) from [" + fileName + "]";
           
        OleDbCommand cmd = new OleDbCommand(sqlScalar, conn);
        nTotalFileRows = (int)cmd.ExecuteScalar();
        nTotalPages = nTotalFileRows / nPageSize;

        //set the maximum property equals to the total lines 
        this.vScrollBar1.Maximum = nTotalFileRows;
           
        LoadDataPage(0,nPageSize);
        if (bFirstIteration)
          {
              dataGridView1.DataSource = ds.Tables[0];
              bFirstIteration = false;
           }
           
     }
     catch (Exception ex) //Error
     {
          MessageBox.Show(ex.Message);
     }
  } 

Now to get a new chunk of data on scroll event, write code in the VScrollBar scroll event.
The LoadDataPage function used in the code below will fetch the next page from the file and update the underlying datasource:

C#
private void vScrollBar1_Scroll(object sender, ScrollEventArgs e)
 {
    this.SuspendLayout();
    if (e.ScrollOrientation == ScrollOrientation.VerticalScroll)
      {
         if (e.Type == ScrollEventType.SmallIncrement)
            {
               nStartPosition++;
               LoadDataPage(nStartPosition, nPageSize);
             }
         else if (e.Type == ScrollEventType.SmallDecrement)
             {
               if (nStartPosition > 0)
                {
                 nStartPosition--;
                 LoadDataPage(nStartPosition, nPageSize);
                }
             }
         else if (e.Type == ScrollEventType.LargeIncrement)
             {
               nStartPosition += vScrollBar1.LargeChange;

               LoadDataPage(nStartPosition, nPageSize);
             }
         else if (e.Type == ScrollEventType.LargeDecrement)
             {
               nStartPosition -= vScrollBar1.LargeChange;

               LoadDataPage(nStartPosition, nPageSize);
             }
         else if (e.Type == ScrollEventType.ThumbTrack)
             {
               nStartPosition = e.NewValue;
             }
         else if (e.Type == ScrollEventType.ThumbPosition)
             {
               if (nStartPosition - 1 > 0)
                  nStartPosition -= 1;
               LoadDataPage(nStartPosition, nPageSize);
             }
      }
      this.ResumeLayout();
 }

Paging on Mouse Wheel

To implement paging on mouse wheel, you have to implement the MouseWheel event.

C#
DataGridView.MouseWheel += new
MouseEventHandler(timeSeriesItemsDataGrid_MouseWheel);  

In this event, you can identify through the e.Delta property to show the previous or next record.

C#
private void DataGridView_MouseWheel(object sender, MouseEventArgs e)
 {
    try
    {
      this.SuspendLayout();
      if(e.Delta < 0) 
        {
          if (nStartPosition + nPageSize <= nTotalFileRows)
            {
               vScrollDGV.Value = nStartPosition++;
               LoadDataPage(nStartPosition, nPageSize);
            }
             DeltaValue = e.Delta;
         }
       else if (e.Delta > 0)
         {
          if (nStartPosition > 0)
            {
               vScrollDGV.Value = nStartPosition--;
               LoadDataPage(nStartPosition, nPageSize);
            }
            DeltaValue = e.Delta;
         }
       this.ResumeLayout();
    }
   catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }
 } 

The mouse wheel combines the features of a wheel and a mouse button. The wheel has discrete, evenly spaced notches. When you rotate the wheel, a wheel message is sent as each notch is encountered. One wheel notch, a detent, is defined by the Windows constant WHEEL_DELTA, which is 120. A positive value indicates that the wheel was rotated forward, away from the user; a negative value indicates that the wheel was rotated backward, towards the user.

Currently, a value of 120 is the standard for one detent. If higher resolution mice are introduced, the definition of WHEEL_DATA might become smaller. Most applications should check for a positive or negative value rather than an aggregate total.

Points of Interest

The next step will be to implement paging on resizing the grid control.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Australia Australia
10+ years of Progamming Experience in C++,vb6.0,Delphi 5 & 7,VB.Net,C#.Net & ASP.Net
MCP for Windows Application Development using C#
MCP for Web based Application Development using C#

Comments and Discussions

 
GeneralMy vote of 2 [modified] Pin
Bigdeak14-Jun-10 5:03
Bigdeak14-Jun-10 5:03 
GeneralEnhanced version of this Application Pin
Nouman_gcu24-Nov-09 3:13
Nouman_gcu24-Nov-09 3:13 
Generalsorry! I can't add MouseWheel event Pin
wohahaha16-Aug-09 20:49
wohahaha16-Aug-09 20:49 
GeneralVirtual mode Pin
jroland23-Oct-07 9:13
jroland23-Oct-07 9:13 
GeneralRe: Virtual mode Pin
Nouman Bhatti23-Oct-07 19:53
Nouman Bhatti23-Oct-07 19:53 
GeneralRe: Virtual mode Pin
jroland29-Oct-07 23:16
jroland29-Oct-07 23:16 
GeneralVirtual mode's implementation is broken Pin
I'm Chris29-Oct-07 23:10
professionalI'm Chris29-Oct-07 23:10 
GeneralI don't get the plot Pin
Joe Sonderegger22-Oct-07 23:28
Joe Sonderegger22-Oct-07 23:28 
What does your code do? It seems like you are trying to implement a virtual list.
This is available already...

Have a nice life!!

GeneralRe: I don't get the plot Pin
Nouman Bhatti23-Oct-07 19:55
Nouman Bhatti23-Oct-07 19:55 
GeneralRe: I don't get the plot Pin
Joe Sonderegger23-Oct-07 20:10
Joe Sonderegger23-Oct-07 20:10 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.