Export (0) Print
Expand All

How to: Customize Cells and Columns in the Windows Forms DataGridView Control by Extending Their Behavior and Appearance

The DataGridView control provides a number of ways to customize its appearance and behavior using properties, events, and companion classes. Occasionally, you may have requirements for your cells that go beyond what these features can provide. You can create your own custom DataGridViewCell class to provide extended functionality.

You create a custom DataGridViewCell class by deriving from the DataGridViewCell base class or one of its derived classes. Although you can display any type of cell in any type of column, you will typically also create a custom DataGridViewColumn class specialized for displaying your cell type. Column classes derive from DataGridViewColumn or one of its derived types.

In the following code example, you will create a custom cell class called DataGridViewRolloverCell that detects when the mouse enters and leaves the cell boundaries. While the mouse is within the cell's bounds, an inset rectangle is drawn. This new type derives from DataGridViewTextBoxCell and behaves in all other respects as its base class. The companion column class is called DataGridViewRolloverColumn.

To use these classes, create a form containing a DataGridView control, add one or more DataGridViewRolloverColumn objects to the Columns collection, and populate the control with rows containing values.

Note Note

This example will not work correctly if you add empty rows. Empty rows are created, for example, when you add rows to the control by setting the RowCount property. This is because the rows added in this case are automatically shared, which means that DataGridViewRolloverCell objects are not instantiated until you click on individual cells, thereby causing the associated rows to become unshared.

Because this type of cell customization requires unshared rows, it is not appropriate for use with large data sets. For more information about row sharing, see Best Practices for Scaling the Windows Forms DataGridView Control.

Note Note

When you derive from DataGridViewCell or DataGridViewColumn and add new properties to the derived class, be sure to override the Clone method to copy the new properties during cloning operations. You should also call the base class's Clone method so that the properties of the base class are copied to the new cell or column.

To customize cells and columns in the DataGridView control

  1. Derive a new cell class, called DataGridViewRolloverCell, from the DataGridViewTextBoxCell type.

    Public Class DataGridViewRolloverCell
        Inherits DataGridViewTextBoxCell
    
    
    ...
    
    
    End Class
    
  2. Override the Paint method in the DataGridViewRolloverCell class. In the override, first call the base class implementation, which handles the hosted text box functionality. Then use the control's PointToClient method to transform the cursor position (in screen coordinates) to the DataGridView client area's coordinates. If the mouse coordinates fall within the bounds of the cell, draw the inset rectangle.

    Protected Overrides Sub Paint( _
        ByVal graphics As Graphics, _
        ByVal clipBounds As Rectangle, _
        ByVal cellBounds As Rectangle, _
        ByVal rowIndex As Integer, _
        ByVal elementState As DataGridViewElementStates, _
        ByVal value As Object, _
        ByVal formattedValue As Object, _
        ByVal errorText As String, _
        ByVal cellStyle As DataGridViewCellStyle, _
        ByVal advancedBorderStyle As DataGridViewAdvancedBorderStyle, _
        ByVal paintParts As DataGridViewPaintParts)
    
        ' Call the base class method to paint the default cell appearance. 
        MyBase.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, _
            value, formattedValue, errorText, cellStyle, _
            advancedBorderStyle, paintParts)
    
        ' Retrieve the client location of the mouse pointer. 
        Dim cursorPosition As Point = _
            Me.DataGridView.PointToClient(Cursor.Position)
    
        ' If the mouse pointer is over the current cell, draw a custom border. 
        If cellBounds.Contains(cursorPosition) Then 
            Dim newRect As New Rectangle(cellBounds.X + 1, _
                cellBounds.Y + 1, cellBounds.Width - 4, _
                cellBounds.Height - 4)
            graphics.DrawRectangle(Pens.Red, newRect)
        End If 
    
    End Sub
    
  3. Override the OnMouseEnter and OnMouseLeave methods in the DataGridViewRolloverCell class to force cells to repaint themselves when the mouse pointer enters or leaves them.

    ' Force the cell to repaint itself when the mouse pointer enters it. 
    Protected Overrides Sub OnMouseEnter(ByVal rowIndex As Integer)
        Me.DataGridView.InvalidateCell(Me)
    End Sub 
    
    ' Force the cell to repaint itself when the mouse pointer leaves it. 
    Protected Overrides Sub OnMouseLeave(ByVal rowIndex As Integer)
        Me.DataGridView.InvalidateCell(Me)
    End Sub
    
  4. Derive a new class, called DataGridViewRolloverCellColumn, from the DataGridViewColumn type. In the constructor, assign a new DataGridViewRolloverCell object to its CellTemplate property.

    Public Class DataGridViewRolloverCellColumn
        Inherits DataGridViewColumn
    
        Public Sub New()
            Me.CellTemplate = New DataGridViewRolloverCell()
        End Sub 
    
    End Class
    

The complete code example includes a small test form that demonstrates the behavior of the custom cell type.

Imports System
Imports System.Drawing
Imports System.Windows.Forms

Class Form1
    Inherits Form

    <STAThreadAttribute()> _
    Public Shared Sub Main()
        Application.Run(New Form1())
    End Sub 

    Public Sub New()
        Dim dataGridView1 As New DataGridView()
        Dim col As New DataGridViewRolloverCellColumn()
        dataGridView1.Columns.Add(col)
        dataGridView1.Rows.Add(New String() {""})
        dataGridView1.Rows.Add(New String() {""})
        dataGridView1.Rows.Add(New String() {""})
        dataGridView1.Rows.Add(New String() {""})
        Me.Controls.Add(dataGridView1)
        Me.Text = "DataGridView rollover-cell demo" 
    End Sub 

End Class 

Public Class DataGridViewRolloverCell
    Inherits DataGridViewTextBoxCell

    Protected Overrides Sub Paint( _
        ByVal graphics As Graphics, _
        ByVal clipBounds As Rectangle, _
        ByVal cellBounds As Rectangle, _
        ByVal rowIndex As Integer, _
        ByVal elementState As DataGridViewElementStates, _
        ByVal value As Object, _
        ByVal formattedValue As Object, _
        ByVal errorText As String, _
        ByVal cellStyle As DataGridViewCellStyle, _
        ByVal advancedBorderStyle As DataGridViewAdvancedBorderStyle, _
        ByVal paintParts As DataGridViewPaintParts)

        ' Call the base class method to paint the default cell appearance. 
        MyBase.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, _
            value, formattedValue, errorText, cellStyle, _
            advancedBorderStyle, paintParts)

        ' Retrieve the client location of the mouse pointer. 
        Dim cursorPosition As Point = _
            Me.DataGridView.PointToClient(Cursor.Position)

        ' If the mouse pointer is over the current cell, draw a custom border. 
        If cellBounds.Contains(cursorPosition) Then 
            Dim newRect As New Rectangle(cellBounds.X + 1, _
                cellBounds.Y + 1, cellBounds.Width - 4, _
                cellBounds.Height - 4)
            graphics.DrawRectangle(Pens.Red, newRect)
        End If 

    End Sub 

    ' Force the cell to repaint itself when the mouse pointer enters it. 
    Protected Overrides Sub OnMouseEnter(ByVal rowIndex As Integer)
        Me.DataGridView.InvalidateCell(Me)
    End Sub 

    ' Force the cell to repaint itself when the mouse pointer leaves it. 
    Protected Overrides Sub OnMouseLeave(ByVal rowIndex As Integer)
        Me.DataGridView.InvalidateCell(Me)
    End Sub 

End Class 

Public Class DataGridViewRolloverCellColumn
    Inherits DataGridViewColumn

    Public Sub New()
        Me.CellTemplate = New DataGridViewRolloverCell()
    End Sub 

End Class

This example requires:

  • References to the System, System.Windows.Forms, and System.Drawing assemblies.

For information about building this example from the command line for Visual Basic or Visual C#, see Building from the Command Line (Visual Basic) or Command-line Building With csc.exe. You can also build this example in Visual Studio by pasting the code into a new project. Also see How to: Compile and Run a Complete Windows Forms Code Example Using Visual Studio.

Show:
© 2014 Microsoft