Procedimiento para personalizar celdas y columnas en el control DataGridView de formularios Windows Forms mediante la ampliación de su comportamiento y apariencia
El control DataGridView ofrece varias maneras de personalizar su apariencia y comportamiento mediante propiedades, eventos y clases complementarias. Ocasionalmente podría tener requisitos para sus celdas que van más allá de lo que pueden proporcionar estas características. Puede crear su propia clase DataGridViewCell personalizado para proporcionar una funcionalidad ampliada.
Puede crear una clase DataGridViewCell derivando de la clase base DataGridViewCell o de una de sus clases derivadas. 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. Las clases de columna derivan de DataGridViewColumn o de uno de sus tipos derivados.
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. Mientras el mouse está dentro de los límites de la celda, se dibuja un rectángulo de bajorrelieve. Este nuevo tipo deriva de DataGridViewTextBoxCell y se comporta en todos los demás aspectos como su clase base. La clase de columna complementaria se llama 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.
Nota:
Este ejemplo no funcionará correctamente si agrega filas vacías. Se crean filas vacías, por ejemplo, cuando se agregan filas al control estableciendo la propiedad RowCount. 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.
Como este tipo de personalización de celda requiere filas no compartidas, no es adecuado para su uso con grandes conjuntos de datos. Para obtener más información sobre cómo compartir filas, consulte Procedimientos recomendados para ajustar la escala del control DataGridView en Windows Forms.
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. 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.
Para personalizar las celdas y columnas del control DataGridView
Derive una nueva clase de celda, llamada
DataGridViewRolloverCell
, del tipo DataGridViewTextBoxCell.public class DataGridViewRolloverCell : DataGridViewTextBoxCell {
Public Class DataGridViewRolloverCell Inherits DataGridViewTextBoxCell
}
End Class
Invalide el método Paint en la clase
DataGridViewRolloverCell
. En la invalidación, llame primero a la implementación de la clase base, que controla la funcionalidad del cuadro de texto hospedado. 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. Si las coordenadas del mouse se encuentran dentro de los límites de la celda, dibuje el rectángulo de bajorrelieve.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
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.// 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
Derive una nueva clase, llamada
DataGridViewRolloverCellColumn
, del tipo DataGridViewColumn. En el constructor, asigne un nuevo objetoDataGridViewRolloverCell
a su propiedad CellTemplate.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
Ejemplo
En el ejemplo de código completo se incluye un pequeño formulario de prueba que muestra el comportamiento del tipo de celda personalizado.
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ódigo
Para este ejemplo se necesita:
- Referencias a los ensamblados System, System.Windows.Forms y System.Drawing.
Consulte también
- DataGridView
- DataGridViewCell
- DataGridViewColumn
- Personalizar el control DataGridView de formularios Windows Forms
- Arquitectura del control DataGridView
- Tipos de columnas en el control DataGridView de formularios Windows Forms
- Procedimientos recomendados para ajustar la escala del control DataGridView en formularios Windows Forms
.NET Desktop feedback