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
|