There are five samples in this solution to demonstrate DataGridView:

1.       CustomDataGridViewColumn:

This sample demonstrates how to create a custom DataGridView column.

2.       DataGridViewPaging:

This sample demonstrates how to page data in the  DataGridView control.

3.       EditingControlHosting:

This sample demonstrates how to host a control in the current DataGridViewCell  for editing.

4.       JustInTimeDataLoading:

If you are working with a very large table in a remote database, for example, you might want to avoid startup delays by retrieving only the data that is necessary for display and retrieving additional data only when the user scrolls  new rows into view. If the client computers running your application have a  limited amount of memory available for storing data, you might also want to  discard unused data when retrieving new values from the database.

This sample demonstrates how to use virtual mode in the DataGridView control  with a data cache that loads data from a server only when it is needed.  This kind of data loading is called "Just-in-time data loading".

5.       MultipleLayeredColumnHeader:

This sample demonstrates how to display multiple layer column headers on the DataGridView contorl.

Running the Sample

1.       CustomDataGridViewColumn.


2.       DataGridViewPaging.


3.       EditingControlHosting.


4.       JustInTimeDataLoading.


5.       MultipleLayeredColumnHeader.



Using the Code

1.       CustomDataGridViewColumn.

There're six standard DataGridViewColumn types for use as follows:

However, developers may want to use a different control for editing on the column, e.g. MarkedTextBox, DateTimePicker etc. This feature can be achieved in two ways:

A. Create a custom DataGridViewColumn;

   The code in this CustomDataGridViewColumn sample demonstrates how to do this;

B. Place the editing control on the current cell when editing begins, and hide the editing control when the editing completes. For the details of this approach, please refer to the   EditingControlHosting sample.

2.       DataGridViewPaging

A. Get total count of the rows in the table;

B. Calculate total count of pages;

C. Load each page on demand;

3.       EditingControlHosting

A. Create an instance of the editing control, in this sample the editing control is MaskedTextBox.   

B. Specify a mask for the MaskedTextBox and add the MaskedTextBox to the control collection of the DataGridView;  

C. Hide the MaskedTextBox;

D. Handle the CellBeginEdit event to show the MaskedTextBox on the current editing cell;  

E. Handle the CellEndEdit event to hide the MaskedTextBox when editing completes;

F. Handle the Scroll event to adjust the location of the MaskedTextBox as it is showing when scrolling the DataGridView;

G. Handle the EditingControlShowing event to pass the focus to the MaskedTextBox when begin editing with keystrokes;

4.       JustInTimeDataLoading

A.  Enable VirtualMode on the DataGridView control by setting the VirtualMode property to true:   

' Enable VirtualMode on the DataGridView 
Me.dataGridView1.VirtualMode = True 

B.  Add columns to the DataGridView according to the data in the database;

C.  Retrieve the row count of the data in the database and set the RowCount  property for the DataGridView;   

            ' Handle the CellValueNeeded event to retrieve the requested cell value 
            ' from the data store or the Customer object currently in edit. 
            ' This event occurs whenever the DataGridView control needs to paint a cell. 
            ' Create a DataRetriever and use it to create a Cache object 
            ' and to initialize the DataGridView columns and rows. 
                Dim retriever As DataRetriever = New DataRetriever(connectionString, table) 
                memoryCache = New Cache(retriever, 16
                For Each column As DataColumn In retriever.Columns 
                    dataGridView1.Columns.Add(column.ColumnName, column.ColumnName) 
                Me.dataGridView1.RowCount = retriever.RowCount 
            Catch ex As Exception 
                MessageBox.Show("Connection could not be established. " + _ 
                    "Verify that the connection string is valid."
            End Try 

D.  Handle the CellValueNeeded event to retrieve the requested cell value from the data store or the Customer object currently in edit.

Private Sub dataGridView1_CellValueNeeded(ByVal sender As System.ObjectByVal e As System.Windows.Forms.DataGridViewCellValueEventArgs) Handles dataGridView1.CellValueNeeded 
    e.Value = memoryCache.RetrieveElement(e.RowIndex, e.ColumnIndex) 
End Sub 

5.       MultipleLayeredColumnHeader

A.  Enable resizing on the column headers by setting the ColumnHeadersHeightSizeMode property as follows:

' Enable resizing on the column headers 
          Me.dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.EnableResizing 

B.  Adjust the height for the column headers to make it wide enough for two layers;

' Adjust the height for the column headers 
Me.dataGridView1.ColumnHeadersHeight = Me.dataGridView1.ColumnHeadersHeight * 2 

C.  Adjust the text alignment on the column headers to make the text display at the center of the bottom;   

             ' Adjust the text alignment on the column headers to make the text display 
           ' at the center of the bottom 
           Me.dataGridView1.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.BottomCenter 
           ' Handle the CellPainting event to draw text for each header cell 

D.  Handle the DataGridView.CellPainting event to draw text for each header  cell;

Private Sub dataGridView1_CellPainting(ByVal sender As System.ObjectByVal e As System.Windows.Forms.DataGridViewCellPaintingEventArgs) Handles dataGridView1.CellPainting 
           If e.RowIndex = -1 AndAlso e.ColumnIndex > -1 Then 
               e.PaintBackground(e.CellBounds, False) 
               Dim r2 As Rectangle = e.CellBounds 
               r2.Y += e.CellBounds.Height / 2 
               r2.Height = e.CellBounds.Height / 2 
               e.Handled = True 
           End If 
       End Sub 

E.  Handle the DataGridView.Paint event to draw "merged" header cells;

Private Sub dataGridView1_Paint(ByVal sender As System.ObjectByVal e As System.Windows.Forms.PaintEventArgs) Handles dataGridView1.Paint 
           ' Data for the "merged" header cells 
           Dim monthes As String() = {"January""February""March"} 
           For j As Integer = 0 To Me.dataGridView1.ColumnCount - 1 Step 2 
               ' Get the column header cell bounds 
               Dim r1 As Rectangle = Me.dataGridView1.GetCellDisplayRectangle(j, -1True) 
               r1.X += 1 
               r1.Y += 1 
               r1.Width = r1.Width * 2 - 2 
               r1.Height = r1.Height / 2 - 2 
               Using br As SolidBrush = New SolidBrush(Me.dataGridView1.ColumnHeadersDefaultCellStyle.BackColor) 
                   e.Graphics.FillRectangle(br, r1) 
               End Using 
               Using p As Pen = New Pen(SystemColors.InactiveBorder) 
                   e.Graphics.DrawLine(p, r1.X, r1.Bottom, r1.Right, r1.Bottom) 
               End Using 
               Using format As StringFormat = New StringFormat() 
                   Using br As SolidBrush = New SolidBrush(Me.dataGridView1.ColumnHeadersDefaultCellStyle.ForeColor) 
                       format.Alignment = StringAlignment.Center 
                       format.LineAlignment = StringAlignment.Center 
                       e.Graphics.DrawString(monthes(j / 2), Me.dataGridView1.ColumnHeadersDefaultCellStyle.Font, _ 
                                             br, r1, format) 
                   End Using 
               End Using 
       End Sub 

More Information

��         Windows Forms FAQs

��         DataGridView Class  

��         DataGridView Custom Column Sample

��         Implementing Virtual Mode with Just-In-Time Data Loading in the Windows Forms DataGridView Control.  

Last edited Feb 13, 2013 at 7:34 AM by super_J, version 2