Agregando funcionalidad al control DataGrid con VB .NET
[Validar, Calcular y restringir es posible en el DataGrid]

Fecha: 11/Ago/2004 (11/Agosto/2004)
Autor: Eduardo Puchades Fuentes
yosull@(quitar esto)hotmail.com


En este ejemplo de código vamos a ver como agregar funcionalidad al Control DataGrid con VB .NET


 

Entre las funcionalidades que agregaremos están el poder agregar columnas calculadas dinámicamente al DataGrid, poder darle formato a las columnas, poder evitar o permitir agregar mas registros en el DataGrid (el registro que aparece al final del DataGrid con un asterisco *),  Poder validar las teclas presionadas por el usuario a fin de permitir solo números o bien convertir las letras minúsculas a MAYÚSCULAS y finalmente el poder sumar una columna completa de manera rápida y colocar su resultado dinámicamente en un control Label  

 
'****************************************************************************
'* Código realizado por Eduardo Puchades Fuentes © (Mexicano) ;-)                                             * 
'****************************************************************************
Public Class Form1
   Inherits System.Windows.Forms.Form

#Region " Código generado por el Diseñador de Windows Forms "

' Este código decidí quitarlo para ahorrar espacio si desea el código completo puede descargar el fichero .zip que se encuentra al final de esta página  

#End Region

   Private Sub CheckBox5_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox5.CheckedChanged
      ' Aquí cambiamos el valor de AllowNew para 
      ' evitar o permitir agregar registros
      ' a nuestro DataGrid

      Dim Valor As Boolean

      If sender.Checked = True Then
         Valor = False
      Else
         Valor = True
      End If

      'Instanciamos y creamos nuestro manejador
      Dim cm As CurrencyManager
      cm = CType(BindingContext(DataSet1, Me.DataSet1.Tables(0).TableName), CurrencyManager)
      'Instanciamos y creamos un DataView asociado a nuestro manejador CurrencyManager
      Dim Dv As DataView = CType(cm.List, DataView)
      'Asignamos el valor que deseamos para evitar o permitir nuevos registros
      Dv.AllowNew = Valor

   End Sub

   Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
      'Cargamos nuestro DataSet leyendo nuestro archivo XML que contiene los datos
      Me.DataSet1.ReadXml("..\Datos.xml")
      'Asignamos el DataSource y el DataMember de nuestro DataGrid
      Me.DataGrid1.DataSource = Me.DataSet1
      Me.DataGrid1.DataMember = Me.DataSet1.Tables(0).TableName

   End Sub

   Private Sub CheckBox2_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox2.CheckedChanged
      'Aquí vamos a agregar una columna en tiempo de ejecución 
      'llamada Cantidad para que el usuario pueda cambiar la cantidad

      If sender.Checked = True Then
         'Cambiamos el estado del cursor poniendo un reloj de arena 
         Me.Cursor = System.Windows.Forms.Cursors.WaitCursor
         'Declaramos una variable de DataColumn y creamos la columna
         Dim MiColum As DataColumn = New DataColumn
         MiColum.DataType = System.Type.GetType("System.Int32")
         MiColum.AllowDBNull = False
         MiColum.DefaultValue = 1
         MiColum.Caption = "Cantidad"
         MiColum.ColumnName = "Cantidad"
         'Agregamos la columna a la colección de columnas del DataSet1
         Me.DataSet1.Tables(0).Columns.Add(MiColum)
         'Regresamos el estado del cursor a normal
         Me.Cursor = System.Windows.Forms.Cursors.Default
      End If
   End Sub

   Private Sub CheckBox3_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox3.CheckedChanged
      'Aquí vamos a agregar una columna calculada dinámicamente
      'y llamada SubTotal para multiplicar la columna Precio x cantidad

      If sender.Checked = True Then
         'Verificamos que ya esté agregada la columna de Cantidad
         If Me.DataSet1.Tables(0).Columns.Count = 3 And Me.CheckBox2.Checked = False Then Me.CheckBox2.Checked = True
         'Cambiamos el estado del cursor poniendo un reloj de arena 
         Me.Cursor = System.Windows.Forms.Cursors.WaitCursor
         'Declaramos una variable de DataColumn y creamos la columna
         Dim MiColum As DataColumn = New DataColumn
         MiColum.DataType = System.Type.GetType("System.Decimal")
         MiColum.AllowDBNull = False
         MiColum.DefaultValue = 1
         MiColum.Caption = "Sub Total"
         MiColum.ColumnName = "SubTotal"
         'Aplicamos el tipo de operación que deseamos 
         MiColum.Expression = "Precio * Cantidad"
         'Agregamos la columna a la colección de columnas del DataSet1
         Me.DataSet1.Tables(0).Columns.Add(MiColum)
         'Regresamos el estado del cursor a normal
         Me.Cursor = System.Windows.Forms.Cursors.Default
      End If
   End Sub

   Private Sub CheckBox4_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox4.CheckedChanged
      'Aquí vamos a agregar una columna calculada dinámicamente
      'y llamada Impuesto para multiplicar la columna SubTotal x .1

      If sender.Checked = True Then
         'Verificamos que ya esté agregada la columna de Sub Total
         If Me.DataSet1.Tables(0).Columns.Count <= 4 And Me.CheckBox3.Checked = False Then Me.CheckBox3.Checked = True
         'Cambiamos el estado del cursor poniendo un reloj de arena 
         Me.Cursor = System.Windows.Forms.Cursors.WaitCursor
         'Declaramos una variable de DataColumn y creamos la columna
         Dim MiColum As DataColumn = New DataColumn
         MiColum.DataType = System.Type.GetType("System.Decimal")
         MiColum.AllowDBNull = False
         MiColum.DefaultValue = 1
         MiColum.Caption = "Impuesto"
         MiColum.ColumnName = "Impuesto"
         'Aplicamos el tipo de operación que deseamos 
         MiColum.Expression = "SubTotal * .1"
         'Agregamos la columna a la colección de columnas del DataSet1
         Me.DataSet1.Tables(0).Columns.Add(MiColum)
         'Regresamos el estado del cursor a normal
         Me.Cursor = System.Windows.Forms.Cursors.Default
      End If
   End Sub

   Private Sub CheckBox6_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox6.CheckedChanged
      'Aquí vamos a agregar una columna calculada dinámicamente
      'y llamada Total para sumar la columna SubTotal + Impuesto

      If sender.Checked = True Then
         'Verificamos que ya esté agregada la columna de Impuesto
         If Me.DataSet1.Tables(0).Columns.Count <= 5 And Me.CheckBox4.Checked = False Then Me.CheckBox4.Checked = True
         'Cambiamos el estado del cursor poniendo un reloj de arena 
         Me.Cursor = System.Windows.Forms.Cursors.WaitCursor
         'Declaramos una variable de DataColumn y creamos la columna
         Dim MiColum As DataColumn = New DataColumn
         MiColum.DataType = System.Type.GetType("System.Decimal")
         MiColum.AllowDBNull = False
         MiColum.DefaultValue = 1
         MiColum.Caption = "Total"
         MiColum.ColumnName = "Total"
         'Aplicamos el tipo de operación que deseamos 
         MiColum.Expression = "SubTotal + Impuesto"
         'Agregamos la columna a la colección de columnas del DataSet1
         Me.DataSet1.Tables(0).Columns.Add(MiColum)
         'Regresamos el estado del cursor a normal
         Me.Cursor = System.Windows.Forms.Cursors.Default
      End If
   End Sub



   Private Sub DataGrid1_CurrentCellChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles DataGrid1.CurrentCellChanged
      'Aquí vamos a sumar toda la columna llamada Total

      'Comprobamos que nuestro DataGrid tenga nuestra columna llamada Total
      If Me.CheckBox7.Checked = True And Me.DataSet1.Tables(0).Columns.Count = 7 Then
         'Declaramos una variable objeto
         Dim objSum As Object
         ' Y Ocupamos la Función Compute del DataTable para sumar y asignar el valor a la variable
         ' Note que estamos ocupando el Nombre de la columna agregada como Total en Sum(Total)
         ' y después de la coma estamos agregando un filtro para que sume únicamente los registros donde el 
         ' Valor de la columna Total es mayor que 0, así evitamos que al utilizar números negativos 
         ' Estos ocasionen un resultado inesperado, puede ocupar ese filtro para sumar únicamente
         ' Los registros de un producto determinado o un producto con descuento por ejemplo.
         objSum = Me.DataSet1.Tables(0).Compute("Sum(Total)", "Total > 0")
         ' Convertimos el resultado a un string y le damos formato de Moneda
         Me.Label1.Text = Format(CStr(objSum), "Currency")
      End If
   End Sub


   Private Sub CreaFormato()
      'Aquí vamos a aplicar un formato a nuestro DataGrid 
      'y vamos a validar las teclas presionadas en las columnas Precio y Cantidad

      'Borramos la tabla de estilos en el DataGrid si es que existe
      Me.DataGrid1.TableStyles.Clear()

      'Instanciamos y creamos una nueva tabla de estilos
      Dim TableStyle1 As New DataGridTableStyle
      'Le indicamos el nombre de la tabla de nuestro DataSet
      TableStyle1.MappingName = Me.DataSet1.Tables(0).TableName
      'Creamos un formato de celdas Alternando el color blanco del fondo
      'con un color gris claro
      TableStyle1.AlternatingBackColor = Color.LightGray


      'Instanciamos y creamos nuestro primer formato de columna
      Dim TextCol1 As New DataGridTextBoxColumn
      'Le indicamos el nombre de la columna 
      TextCol1.MappingName = "IDProducto"
      'Le indicamos el nombre que deseamos aparezca en el encabezado de la columna
      TextCol1.HeaderText = "IDProducto"
      'Le indicamos el ancho de la columna
      TextCol1.Width = 70
      'Agregamos nuestro formato de columna a la colección de nuestra Tabla de estilos
      TableStyle1.GridColumnStyles.Add(TextCol1)


      'Instanciamos y creamos nuestro segundo formato de columna
      Dim TextCol2 As New DataGridTextBoxColumn
      'Le indicamos el nombre de la columna 
      TextCol2.MappingName = "Nombre"
      'Le indicamos el nombre que deseamos aparezca en el encabezado de la columna
      TextCol2.HeaderText = "Nombre"
      'Le indicamos el ancho de la columna
      TextCol2.Width = 120
      'Agregamos nuestro formato de columna a la colección de nuestra Tabla de estilos
      TableStyle1.GridColumnStyles.Add(TextCol2)


      'MUCHO OJO AQUÍ
      'Aquí vamos a instanciar y crear nuestro tercer formato de columna
      'Pero puede usted notar que estoy ocupando una clase llamada 
      'DataGridTextBoxColumnSoloNumeros esta clase es una clase que previamente he
      'Creado y esta clase es un componente heredado de DataGridTextBoxColumn
      'A esta clase heredada le he agregado la Funcionalidad de permitirnos
      'Validar las teclas que presionan los usuarios, evitando de esta manera
      'que inserten letras donde solo deben ir números
      'En esta clase también he agregado un ejemplo para poder convertir  
      'las teclas presionadas por el usuario de minúsculas a MAYÚSCULAS

      'Instanciamos y creamos nuestro Tercer Formato de columna
      'ocupando la clase antes mencionada
      Dim TextCol3 As New DataGridTextBoxColumnSoloNumeros
      'Le indicamos que la alineación la queremos del lado derecho
      TextCol3.Alignment = HorizontalAlignment.Right
      'Le indicamos el nombre de la columna 
      TextCol3.MappingName = "Precio"
      'Le indicamos el nombre que deseamos aparezca en el encabezado de la columna
      TextCol3.HeaderText = "Precio"
      'Le indicamos el ancho de la columna
      TextCol3.Width = 60
      'Aquí con la letra "c" le estamos indicando que queremos un formato currency (Moneda)
      TextCol3.Format = "c"
      'Agregamos nuestro formato de columna a la colección de nuestra Tabla de estilos
      TableStyle1.GridColumnStyles.Add(TextCol3)

      'Instanciamos y creamos nuestro Cuarto Formato de columna
      'ocupando la clase antes mencionada
      Dim TextCol4 As New DataGridTextBoxColumnSoloNumeros
      'Le indicamos que la alineación la queremos del lado derecho
      TextCol4.Alignment = HorizontalAlignment.Right
      'Le indicamos el nombre de la columna 
      TextCol4.MappingName = "Cantidad"
      'Le indicamos el nombre que deseamos aparezca en el encabezado de la columna
      TextCol4.HeaderText = "Cantidad"
      'Le indicamos el ancho de la columna
      TextCol4.Width = 60
      'Aquí con la letra "g" le estamos indicando que queremos un formato de número general
      TextCol4.Format = "g"
      'Agregamos nuestro formato de columna a la colección de nuestra Tabla de estilos
      TableStyle1.GridColumnStyles.Add(TextCol4)


      'Instanciamos y creamos nuestro segundo formato de columna
      Dim TextCol5 As New DataGridTextBoxColumn
      'Le indicamos que la alineación la queremos del lado derecho
      TextCol5.Alignment = HorizontalAlignment.Right
      'Le indicamos el nombre de la columna 
      TextCol5.MappingName = "SubTotal"
      'Le indicamos el nombre que deseamos aparezca en el encabezado de la columna
      TextCol5.HeaderText = "Sub total"
      'Le indicamos el ancho de la columna
      TextCol5.Width = 60
      'Aquí con la letra "c" le estamos indicando que queremos un formato currency (Moneda)
      TextCol5.Format = "c"
      'Agregamos nuestro formato de columna a la colección de nuestra Tabla de estilos
      TableStyle1.GridColumnStyles.Add(TextCol5)


      'Instanciamos y creamos nuestro segundo formato de columna
      Dim TextCol6 As New DataGridTextBoxColumn
      'Le indicamos que la alineación la queremos del lado derecho
      TextCol6.Alignment = HorizontalAlignment.Right
      'Le indicamos el nombre de la columna 
      TextCol6.MappingName = "Impuesto"
      'Le indicamos el nombre que deseamos aparezca en el encabezado de la columna
      TextCol6.HeaderText = "Impuesto"
      'Le indicamos el ancho de la columna
      TextCol6.Width = 60
      'Aquí con la letra "c" le estamos indicando que queremos un formato currency (Moneda)
      TextCol6.Format = "c"
      'Agregamos nuestro formato de columna a la colección de nuestra Tabla de estilos
      TableStyle1.GridColumnStyles.Add(TextCol6)


      'Instanciamos y creamos nuestro segundo formato de columna
      Dim TextCol7 As New DataGridTextBoxColumn
      'Le indicamos que la alineación la queremos del lado derecho
      TextCol7.Alignment = HorizontalAlignment.Right
      'Le indicamos el nombre de la columna 
      TextCol7.MappingName = "Total"
      'Le indicamos el nombre que deseamos aparezca en el encabezado de la columna
      TextCol7.HeaderText = "Total"
      'Le indicamos el ancho de la columna
      TextCol7.Width = 60
      'Aquí con la letra "c" le estamos indicando que queremos un formato currency (Moneda)
      TextCol7.Format = "c"
      'Agregamos nuestro formato de columna a la colección de nuestra Tabla de estilos
      TableStyle1.GridColumnStyles.Add(TextCol7)



      Me.DataGrid1.TableStyles.Add(TableStyle1)

   End Sub

   Private Sub CheckBox1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox1.CheckedChanged
      If sender.Checked = True Then
         CreaFormato()
      Else
         Me.DataGrid1.TableStyles.Clear()
      End If
   End Sub
End Class
 

Aquí termina el código del Form1

NOTA: este código no incluye la sección de código generado por el diseñador de Windows Forms
si quiere el código completo puede descargar el fichero .zip al final de esta página

 

Esta es la clase heredada de DataGridTextBoxColumn para validar las teclas presionadas en el DataGrid.

Option Strict Off
Option Explicit On 

Imports Microsoft.VisualBasic
Imports System
Imports System.ComponentModel
Imports System.Windows.Forms

Public Class DataGridTextBoxColumnSoloNumeros

   Inherits DataGridTextBoxColumn



   Public Sub New()
      MyBase.New()
      AddHandler Me.TextBox.KeyPress, New System.Windows.Forms.KeyPressEventHandler(AddressOf HandleKeyPress)

   End Sub



   Private Sub HandleKeyPress(ByVal sender As Object, ByVal e As KeyPressEventArgs)
      'Aquí puede cambiar el código para que el usuario unicamente presione letras
      'o para cambiar las letras minúsculas por MAYÚSCULAS con el ejemplo siguiente
      'If e.KeyChar.IsLower(e.KeyChar) Then
      '   e.KeyChar.ToUpper(e.KeyChar)
      'End If




      'Ignora la tecla presionada si no es dígito o tecla de control
      If e.KeyChar.IsDigit(e.KeyChar) Then
         e.Handled = False
      ElseIf e.KeyChar.IsControl(e.KeyChar) Then
         e.Handled = False
      Else
         e.Handled = True
      End If

      'Ignora la tecla presionada si el valor es mas grande de cuatro dígitos
      If ((Me.TextBox.Text.Length >= 4) AndAlso Not (e.KeyChar.IsControl(e.KeyChar)) AndAlso Me.TextBox.SelectionLength = 0) Then
         e.Handled = True
      End If

   End Sub

End Class




ir al índice

Fichero con el código de ejemplo: yosall_datagrid.zip - Tamaño KB