Personalizar DataGridView (II) - Bloquear columnas de solo lectura.
Personalizar DataGridView - Actualizaciones.
Personalizar DataGridView (II.1) - Bloquear columnas de solo lectura.
Personalizar DataGridView (III) - Cambiar Diseñador.
Bien, como lo dice el titulo vamos a personalizar el control DataGridView y lo haremos en varios artículos, en este lo que hare es pintar el área del control que queda vacía cuando tenemos un origen de datos con pocos registros, a esta área la llamare "Empty Area", así que en lugar de que se vea de esta manera.
Personalizar DataGridView - Actualizaciones.
Personalizar DataGridView (II.1) - Bloquear columnas de solo lectura.
Personalizar DataGridView (III) - Cambiar Diseñador.
Bien, como lo dice el titulo vamos a personalizar el control DataGridView y lo haremos en varios artículos, en este lo que hare es pintar el área del control que queda vacía cuando tenemos un origen de datos con pocos registros, a esta área la llamare "Empty Area", así que en lugar de que se vea de esta manera.
haré que se vea de esta otra manera.
para esto crearemos nuestro propio control que herede de DataGridView al cual llamare MEPDataGridView, sobre escribiremos los métodos OnCellPainting y OnPaint del control, creare 5 métodos auxiliares "PaintColumnHeader", "PaintIndicatorHeader", "PaintRowIndicator", "PaintCell" y "PaintEmptyArea" y un Argumento "PaintingEventArgs" que hereda de EventArgs que sera pasado a algunos de los métodos auxiliares.
[C#]
public class MEPDataGridView : DataGridView
{
public MEPDataGridView()
{
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
this.SetStyle(ControlStyles.ResizeRedraw, true);
this.DoubleBuffered = true;
}
}
[VB.NET]
Public Class MEPDataGridView
Inherits DataGridView
Public Sub New()
Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
Me.SetStyle(ControlStyles.ResizeRedraw, True)
Me.DoubleBuffered = True
End Sub
End Class
como bien podemos observar en el constructor he activado el DoubleBuffer para reducir el parpadeo (flicker) al dibujar el control cuando este cambie de dimensiones, para mayor referencia ControlStyles.
desde este articulo dibujare los encabezados de las columnas para mantener uniformidad en los colores de estas ya que al tener habilitados los estilos visuales para la aplicación "Application.EnableVisualStyles", es dificil obtener los colores predeterminados con que se pintan los encabezados, y en este caso necesito hacerlo así para mantener uniformidad al pintar la columna indicador en el "Empty Area".
Ahora agregaremos una nueva propiedad al control para indicarle cuando queremos que se pinten las filas en el "Empty Area", ha esta propiedad la llamare "FillEmptyArea" cuyo tipo sera "Boolean" true/false, cuyo valor predeterminado sera "false".
[C#]
private bool vFillEmptyArea;
[DefaultValue(false)]
public bool FillEmptyArea
{
get
{
return this.vFillEmptyArea;
}
set
{
this.vFillEmptyArea = value;
if (this.IsHandleCreated)
this.Invalidate(true);
}
}
[VB.NET]
Private vFillEmptyArea As Boolean
<DefaultValue(False)> _
Public Property FillEmptyArea() As Boolean
Get
Return Me.vFillEmptyArea
End Get
Set(ByVal value As Boolean)
Me.vFillEmptyArea = value
If Me.IsHandleCreated Then
Me.Invalidate(True)
End If
End Set
End Property
Ademas hare visible la propiedad “AutoGenerateColumns” para poder cambiar esta desde las propiedades del control en tiempo de diseño.
[C#]
[Browsable(true), DefaultValue(true)]
public new virtual bool AutoGenerateColumns
{
get
{
return vAutoGenerateColumns;
}
set
{
vAutoGenerateColumns = value;
base.AutoGenerateColumns = value;
}
}
[VB.NET]
<Browsable(True), DefaultValue(True)> _
Public Overloads Property AutoGenerateColumns() As Boolean
Get
Return Me.vAutoGenerateColumns
End Get
Set(ByVal value As Boolean)
Me.vAutoGenerateColumns = value
MyBase.AutoGenerateColumns = value
End Set
End Property
Ahora sobre escribiremos el evento "OnCellPainting" del control para dibujar los encabezados de las columnas y dibujar el indicador de la fila de cada registro del origen de datos.
[C#]
protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e)
{
base.OnCellPainting(e);
if (e.RowIndex == -1 && e.ColumnIndex == -1)
{
// Método auxiliar para pintar el encabezado de la columna indicador.
this.PaintIndicatorHeader(e);
}
else if (e.RowIndex == -1 && e.ColumnIndex > -1)
{
// Método auxiliar para pinta los encabezados de las columnas
this.PaintColumnHeader(new PaintingEventArgs(e.Graphics, e.CellBounds, e.RowIndex, e.ColumnIndex));
e.PaintContent(e.ClipBounds);
e.Handled = true;
}
else if (e.ColumnIndex == -1)
{
// Método auxiliar para pinta la columna indicador.
this.PaintRowIndicator(new PaintingEventArgs(e.Graphics, e.CellBounds, e.RowIndex, e.ColumnIndex));
e.PaintContent(e.ClipBounds);
e.Handled = true;
}
}
[VB.NET]
Protected Overrides Sub OnCellPainting(ByVal e As DataGridViewCellPaintingEventArgs)
MyBase.OnCellPainting(e)
If e.RowIndex = -1 And e.ColumnIndex = -1 Then
' Método auxiliar para pintar el encabezado de la columna indicador.
Me.PaintIndicatorHeader(e)
ElseIf e.RowIndex = -1 And e.ColumnIndex > -1 Then
' Método auxiliar para pinta los encabezados de las columnas
Me.PaintColumnHeader(New PaintingEventArgs(e.Graphics, e.CellBounds, e.RowIndex, e.ColumnIndex))
e.PaintContent(e.ClipBounds)
e.Handled = True
ElseIf e.ColumnIndex = -1 Then
' Método auxiliar para pinta la columna indicador.
Me.PaintRowIndicator(New PaintingEventArgs(e.Graphics, e.CellBounds, e.RowIndex, e.ColumnIndex))
e.PaintContent(e.ClipBounds)
e.Handled = True
End If
End Sub
Luego sobre escribimos el evento "OnPaint" para dibujar las filas o lineas para llenar el "Empty Area"[C#]
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (this.FillEmptyArea)
// Método auxiliar para pintar el área vacía
this.PaintEmptyArea(e);
}
[VB.NET]
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
MyBase.OnPaint(e)
If Me.FillEmptyArea Then _
Me.PaintEmptyArea(e) ' Método auxiliar para pintar el área vacía
End Sub
y aquí les dejos los proyectos para que los descarguen.
Código fuente [C#]
Código fuente [VB.NET]
En el próximo artículo veremos como evitar que el usuario pueda colocarse sobre las columnas cuya propiedad "ReadOnly" este establecida en "true".
Espero que sea de utilidad este artículo y no olviden dejar sus comentarios.
Salu2,


Excelente trabajo, gracias.
ResponderEliminar