Colaboraciones en el Guille

Personalizando el Datagrid

Cambiando el color de las filas cuando se cumple cierta condición.

Fecha: 29/Abr/2006 (28/04/06)
Autor: Ezequiel M. Buttiero - ebuttiero@arnet.com.ar

 


En este artículo se trata de mostrar de forma sencilla como pintar filas de una grilla dependiendo del cumplimiento de cierta condición.

Para empezar, utilizamos un control DataGrid para mostrar un conjunto de datos en un formulario Windows, este DataGrid puede ser personalizado mediate la definición de distintos TableStyles (DataGridTableStyle). En estos TableStyles se define el estilo de cada una de las columnas a mostrar, incluyendo formato del dato, texto del encabezado, etc. Cada una de estas columnas son objetos de tipo DataGridTextBoxColumn o DataGridBoolColumn y “mapean” las columnas del origen de datos.

Para cumplir con el objetivo propuesto, trabajaremos en una nueva versión de la clase DataGridTextBoxColumn, heredándola y sobrescribiendo una de las sobrecargas del método Paint. Luego, definiremos para nuestra grilla un TableStyle que la utilice. Por otro lado crearemos un evento que se disparará cada vez que este método Paint sea invocado y será mediante el cual intercambiaremos información entre las instancias de esta clase y el formulario donde se encuentre la grilla que queremos personalizar, ya que es en él donde determinaremos de que color vamos a pintar cada una de las filas.

Para comenzar, vamos a definir una nueva clase a la que llamaremos CustomDataGridTextBoxColumn que hereda de DataGridTextBoxColumn y sobrescribimos el evento Paint, como se muestra a continuación:

Imports System.Drawing

Public Class CustomDataGridTextBoxColumn
    Inherits System.Windows.Forms.DataGridTextBoxColumn

    Protected Overloads Overrides Sub Paint(ByVal g As Graphics, & _
                        ByVal bounds As Rectangle, & _ 
                        ByVal [source] As CurrencyManager, & _
                        ByVal rowNum As Integer, & _
                        ByVal backBrush As Brush, & _
                        ByVal foreBrush As Brush, & _
                        ByVal alignToRight As Boolean)               
    
    End Sub

End Class

Como dijimos anteriormente, cada vez que este método sea invocado, dispararemos un evento el cual vamos a definir dentro de la clase CustomDataGridTextBoxColumn:

Public Event PaintRow(ByVal args As PaintRowEventArgs)

Este evento será capturado en el formulario donde se encuentre la grilla. El argumento de tipo PaintRowEventArgs nos permitirá conocer cual es el índice de la fila que se esta dibujando. Además, mediante este objeto le indicaremos al método Paint de que color se va a pintar la fila y el texto que contiene
El código para esta clase se dispone a continuación:

Public Class PaintRowEventArgs
    Inherits EventArgs

    Private _rowNum As Integer
    Private _backColor As Brush
    Private _foreColor As Brush

    Public Property RowNumber() As Integer
        Get
            Return _rowNum
        End Get
        Set(ByVal Value As Integer)
            _rowNum = Value
        End Set
    End Property

    Public Property BackColor() As Brush
        Get
            Return _backColor
        End Get
        Set(ByVal Value As Brush)
            _backColor = Value
        End Set
    End Property

    Public Property ForeColor() As Brush
        Get
            Return _foreColor
        End Get
        Set(ByVal Value As Brush)
            _foreColor = Value
        End Set
    End Property
End Class

Ahora que tenemos definidas las clases que necesitaremos, nos concentraremos en el método Paint:

Dim oArgs As New PaintRowEventArgs

oArgs.RowNumber = rowNum

RaiseEvent PaintRow(oArgs)

If Not oArgs.BackColor Is Nothing Then
    backBrush = oArgs.BackColor
End If

If Not oArgs.ForeColor Is Nothing Then
    foreBrush = oArgs.ForeColor
End If

oArgs = Nothing

MyBase.Paint(g, bounds, [source], rowNum, backBrush, foreBrush, alignToRight)
   

Dentro de este método, lo primero que hay que hacer es crear una instancia de la clase PaintRowEventArgs, a la que llamamos oArgs y a la que le asignaremos en su propiedad RowNumber el valor recibido por parámetro que indica el índice de la fila que se esta dibujando (rowNum).
El próximo paso será disparar el evento PaintRow mediante la cláusula RaiseEvent. Como veremos mas adelante, ese evento será capturado en nuestro formulario donde evaluaremos alguna condición y determinaremos los valores para las propiedades BackColor y ForeColor del objeto oArgs. Esta condición puede ser el valor de una columna para esta fila. Una vez tratado el evento, reemplazaremos las variables backBrush y foreBrush por los nuevos valores (si es que los hay) obtenidos desde oArgs, según lo que puede verse en el fragmento de código anterior.
Por último, se llama al método Paint de la clase base para que se dibuje efectivamente la celda (Si.. la celda... este método se invoca por cada celda de cada fila que se esta dibujando.)

Con esto ya tendríamos listo una gran parte del trabajo, restaría definir el TableStyle en nuestro formulario y los handlers para el evento PaintRow de cada columna. En el siguiente código de ejemplo, creamos un TableStyle que se utilizará para darle formato a la grilla cuando enlacemos a esta un objeto de tipo ArrayList (esta lista contendra un objeto con dos propiedades: Valoracion y Nombre).

'Creo el estilo para la grilla
Dim oStyle As New DataGridTableStyle
oStyle.MappingName = "ArrayList"

'Creo las columnas 
Dim oColumStyle1 As New CustomDataGridTextBoxColumn
Dim oColumStyle2 As New CustomDataGridTextBoxColumn
'Columna"Valoracion"
oColumStyle1.MappingName = "Valoracion"
oColumStyle2.HeaderText = "Nombre"
'Columna"Nombre"
oColumStyle1.HeaderText = "Valoracion"
oColumStyle2.MappingName = "Nombre"

'Handler para el evento PaintRow
AddHandler oColumStyle1.PaintRow, AddressOf EstablecerColores
AddHandler oColumStyle2.PaintRow, AddressOf EstablecerColores

'Agrego las columnas al TableStyle
oStyle.GridColumnStyles.Add(oColumStyle1)
oStyle.GridColumnStyles.Add(oColumStyle2)

Me.DataGrid1.TableStyles.Add(oStyle)

Por último definiremos el método EstablecerColores a través del cual determinaremos el color de la fila. En este caso, se evaluá el valor de la columna 0 y en base a este valor se definen colores tanto de fuente como de fondo para la fila que se esta tratando:

Private Sub EstablecerColores(ByVal args As PaintRowEventArgs)

    Dim valor = CInt(Me.DataGrid1.Item(args.RowNumber, 0))
    Select Case valor
        Case 0, 1
            args.ForeColor = Brushes.Red
            args.BackColor = Brushes.Yellow
        Case 2
            args.ForeColor = Brushes.Green
            args.BackColor = Brushes.LightGreen
    End Select

End Sub

Notar que si no se especificá valores para las propiedades ForeColor y BackColor se utilizará el valor por defecto.

El resultado:

Resultado al ejecutar nuestra aplicación de muestra

Espacios de nombres usados en el código de este artículo:

System.Windows.Forms
System.Drawing


Fichero con el código de ejemplo: ebuttiero_PersonalizarDatagrid.zip - 10.2 KB

(MD5 checksum: 7607812A9ABCDFC8EDAF27104F9EB65E)


ir al índice principal del Guille