Procedimiento para personalizar celdas y columnas en el control DataGridView de formularios Windows Forms mediante la ampliación de su comportamiento y aparienciaHow to: Customize Cells and Columns in the Windows Forms DataGridView Control by Extending Their Behavior and Appearance

El control DataGridView ofrece varias maneras de personalizar su apariencia y comportamiento mediante propiedades, eventos y clases complementarias.The DataGridView control provides a number of ways to customize its appearance and behavior using properties, events, and companion classes. Ocasionalmente podría tener requisitos para sus celdas que van más allá de lo que pueden proporcionar estas características.Occasionally, you may have requirements for your cells that go beyond what these features can provide. Puede crear su propia clase DataGridViewCell personalizado para proporcionar una funcionalidad ampliada.You can create your own custom DataGridViewCell class to provide extended functionality.

Puede crear una clase DataGridViewCell derivando de la clase base DataGridViewCell o de una de sus clases derivadas.You create a custom DataGridViewCell class by deriving from the DataGridViewCell base class or one of its derived classes. Aunque puede mostrar cualquier tipo de celda en cualquier tipo de columna, normalmente también creará una clase DataGridViewColumn personalizado especializada para mostrar el tipo de celda.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. Las clases de columna derivan de DataGridViewColumn o de uno de sus tipos derivados.Column classes derive from DataGridViewColumn or one of its derived types.

En el ejemplo de código siguiente, creará una clase de celda personalizada llamada DataGridViewRolloverCell que detecta cuándo el mouse entra y sale de los límites de la celda.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. Mientras el mouse está dentro de los límites de la celda, se dibuja un rectángulo de bajorrelieve.While the mouse is within the cell's bounds, an inset rectangle is drawn. Este nuevo tipo deriva de DataGridViewTextBoxCell y se comporta en todos los demás aspectos como su clase base.This new type derives from DataGridViewTextBoxCell and behaves in all other respects as its base class. La clase de columna complementaria se llama DataGridViewRolloverColumn.The companion column class is called DataGridViewRolloverColumn.

Para usar estas clases, cree un formulario que contenga un control DataGridView, agregue uno o varios objetos DataGridViewRolloverColumn a la colección Columns y rellene el control con filas que contengan valores.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.

Nota

Este ejemplo no funcionará correctamente si agrega filas vacías.This example will not work correctly if you add empty rows. Se crean filas vacías, por ejemplo, cuando se agregan filas al control estableciendo la propiedad RowCount.Empty rows are created, for example, when you add rows to the control by setting the RowCount property. Esto se debe a que las filas agregadas en este caso se comparten automáticamente, lo que significa que no se crean instancias de los objetos DataGridViewRolloverCell hasta que haga clic en cada celda individual, y esto hace que las filas asociadas dejan de estar compartidas.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.

Como este tipo de personalización de celda requiere filas no compartidas, no es adecuado para su uso con grandes conjuntos de datos.Because this type of cell customization requires unshared rows, it is not appropriate for use with large data sets. Para obtener más información sobre el uso compartido de filas, vea prácticas recomendadas para escalar el control DataGridView Windows Forms.For more information about row sharing, see Best Practices for Scaling the Windows Forms DataGridView Control.

Nota

Al derivar de DataGridViewCell o DataGridViewColumn y agregar nuevas propiedades a la clase derivada, asegúrese de invalidar el método Clone para copiar las nuevas propiedades durante las operaciones de clonación.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. También debe llamar al método Clone de la clase base para copiar las propiedades de la clase base a la nueva celda o columna.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.

Para personalizar las celdas y columnas del control DataGridViewTo customize cells and columns in the DataGridView control

  1. Derive una nueva clase de celda, llamada DataGridViewRolloverCell, del tipo DataGridViewTextBoxCell.Derive a new cell class, called DataGridViewRolloverCell, from the DataGridViewTextBoxCell type.

    public class DataGridViewRolloverCell : DataGridViewTextBoxCell
    {
    
    Public Class DataGridViewRolloverCell
        Inherits DataGridViewTextBoxCell
    
    }
    
    End Class
    
  2. Invalide el método Paint en la clase DataGridViewRolloverCell .Override the Paint method in the DataGridViewRolloverCell class. En la invalidación, llame primero a la implementación de la clase base, que controla la funcionalidad del cuadro de texto hospedado.In the override, first call the base class implementation, which handles the hosted text box functionality. Después, use el método PointToClient del control para transformar la posición del cursor (en coordenadas de pantalla) en las coordenadas de área de cliente de DataGridView.Then use the control's PointToClient method to transform the cursor position (in screen coordinates) to the DataGridView client area's coordinates. Si las coordenadas del mouse se encuentran dentro de los límites de la celda, dibuje el rectángulo de bajorrelieve.If the mouse coordinates fall within the bounds of the cell, draw the inset rectangle.

    protected override void Paint(
        Graphics graphics,
        Rectangle clipBounds,
        Rectangle cellBounds,
        int rowIndex,
        DataGridViewElementStates cellState,
        object value,
        object formattedValue,
        string errorText,
        DataGridViewCellStyle cellStyle,
        DataGridViewAdvancedBorderStyle advancedBorderStyle,
        DataGridViewPaintParts paintParts)
    {
        // Call the base class method to paint the default cell appearance.
        base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState,
            value, formattedValue, errorText, cellStyle,
            advancedBorderStyle, paintParts);
    
        // Retrieve the client location of the mouse pointer.
        Point cursorPosition =
            this.DataGridView.PointToClient(Cursor.Position);
    
        // If the mouse pointer is over the current cell, draw a custom border.
        if (cellBounds.Contains(cursorPosition))
        {
            Rectangle newRect = new Rectangle(cellBounds.X + 1,
                cellBounds.Y + 1, cellBounds.Width - 4,
                cellBounds.Height - 4);
            graphics.DrawRectangle(Pens.Red, newRect);
        }
    }
    
    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. Invalide los métodos OnMouseEnter y OnMouseLeave en la clase DataGridViewRolloverCell para forzar que las celdas se vuelvan a dibujar cuando el puntero del mouse entre o salga de ellas.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 override void OnMouseEnter(int rowIndex)
    {
        this.DataGridView.InvalidateCell(this);
    }
    
    // Force the cell to repaint itself when the mouse pointer leaves it.
    protected override void OnMouseLeave(int rowIndex)
    {
        this.DataGridView.InvalidateCell(this);
    }
    
    ' 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 una nueva clase, llamada DataGridViewRolloverCellColumn, del tipo DataGridViewColumn.Derive a new class, called DataGridViewRolloverCellColumn, from the DataGridViewColumn type. En el constructor, asigne un nuevo objeto DataGridViewRolloverCell a su propiedad CellTemplate.In the constructor, assign a new DataGridViewRolloverCell object to its CellTemplate property.

    public class DataGridViewRolloverCellColumn : DataGridViewColumn
    {
        public DataGridViewRolloverCellColumn()
        {
            this.CellTemplate = new DataGridViewRolloverCell();
        }
    }
    
    Public Class DataGridViewRolloverCellColumn
        Inherits DataGridViewColumn
    
        Public Sub New()
            Me.CellTemplate = New DataGridViewRolloverCell()
        End Sub
    
    End Class
    

EjemploExample

En el ejemplo de código completo se incluye un pequeño formulario de prueba que muestra el comportamiento del tipo de celda personalizado.The complete code example includes a small test form that demonstrates the behavior of the custom cell type.

using System;
using System.Drawing;
using System.Windows.Forms;

class Form1 : Form
{
    [STAThreadAttribute()]
    public static void Main()
    {
        Application.Run(new Form1());
    }

    public Form1()
    {
        DataGridView dataGridView1 = new DataGridView();
        DataGridViewRolloverCellColumn col =
            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[] { "" });
        this.Controls.Add(dataGridView1);
        this.Text = "DataGridView rollover-cell demo";
    }
}

public class DataGridViewRolloverCell : DataGridViewTextBoxCell
{
    protected override void Paint(
        Graphics graphics,
        Rectangle clipBounds,
        Rectangle cellBounds,
        int rowIndex,
        DataGridViewElementStates cellState,
        object value,
        object formattedValue,
        string errorText,
        DataGridViewCellStyle cellStyle,
        DataGridViewAdvancedBorderStyle advancedBorderStyle,
        DataGridViewPaintParts paintParts)
    {
        // Call the base class method to paint the default cell appearance.
        base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState,
            value, formattedValue, errorText, cellStyle,
            advancedBorderStyle, paintParts);

        // Retrieve the client location of the mouse pointer.
        Point cursorPosition =
            this.DataGridView.PointToClient(Cursor.Position);

        // If the mouse pointer is over the current cell, draw a custom border.
        if (cellBounds.Contains(cursorPosition))
        {
            Rectangle newRect = new Rectangle(cellBounds.X + 1,
                cellBounds.Y + 1, cellBounds.Width - 4,
                cellBounds.Height - 4);
            graphics.DrawRectangle(Pens.Red, newRect);
        }
    }

    // Force the cell to repaint itself when the mouse pointer enters it.
    protected override void OnMouseEnter(int rowIndex)
    {
        this.DataGridView.InvalidateCell(this);
    }

    // Force the cell to repaint itself when the mouse pointer leaves it.
    protected override void OnMouseLeave(int rowIndex)
    {
        this.DataGridView.InvalidateCell(this);
    }

}

public class DataGridViewRolloverCellColumn : DataGridViewColumn
{
    public DataGridViewRolloverCellColumn()
    {
        this.CellTemplate = new DataGridViewRolloverCell();
    }
}
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

Compilar el códigoCompiling the Code

Para este ejemplo se necesita:This example requires:

  • Referencias a los ensamblados System, System.Windows.Forms y System.Drawing.References to the System, System.Windows.Forms, and System.Drawing assemblies.

Vea tambiénSee also