martes, 16 de febrero de 2010

DataGridView personalizado

Introducción

Muchos de nosotros aprovechamos el control DataGridView como visualizador, sin embargo además puede ser una excelente ayuda para añadir nuevas filas a nuestras estructuras de datos.
 
En un proceso donde la información se estructura mediante columnas y líneas, el objetivo es introducir nuevas filas con la mayor facilidad posible, es entonces cuando nos percatamos de que por defecto el DataGridView actúa de una forma un tanto inconveniente para nuestro cometido. Cada vez que pulsamos ‘enter’ ya sea en modo ‘edición’ el efecto es que nos crea una nueva fila desplazándose acto seguido a la primera celda de la misma (como en Excel), entonces nos obliga a utilizar los cursores para reubicar el ‘foco’ a la celda donde va a continuar nuestra próxima entrada. Realmente es un inconveniente, pues nos hace perder muchísimo tiempo empleándolo en pulsaciones simplemente inútiles.
 
Dicho esto, para poder introducir datos de izquierda a derecha tal y como estamos acostumbrados en la mayoría de situaciones en la que manejamos información, podemos recurrir a varios recursos, os proponemos ver como anulando las funciones ‘ProcessDialogKey’ ‘OnKeyDown’ y rescribiendo el código para que la pulsación de una tecla ‘enter’ sea substituida por un ‘tab’ utilizando un ‘sendkeys’, pudiendo conseguir una mejora increíble en la funcionalidad. También en una segunda propuesta os introducimos a como manejar el direccionamiento de selección de las ‘celdas’ de un DataGridView capturando las pulsaciones en el ‘PreProcessMessage’, ambas heredando la funcionalidad DataGridView y añadiendo a esta personalidad propia.
 
Esperamos que os sea de utilidad… solo tenéis que ¡cortar y pegar!
 

El código:

''
Public Class Form1
    'Mi DGV, que traduce el 'Enter' en 'Tab'
    Private WithEvents _MiDGView1 As New DgvPlus
    'Mi DGV, que controla la posicion de la celda actual
    Private WithEvents _MiDGView2 As New MiDGView
    '
    ' al lanzar nuestro form (en el momento de carga)
    Private Sub Form1_Load(ByVal sender As Object, _
                ByVal e As System.EventArgs) Handles Me.Load
        '
        'Construir el primer DGV
        '
        'Acoplarlo a la izquierda
        _MiDGView1.Dock = DockStyle.Left
        'con cuatro columnas
        _MiDGView1.ColumnCount = 4
        'Ajustarlo al tamaño
        _MiDGView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
        'Etiquetar columna
        _MiDGView1.Columns(0).HeaderText = "Caso A"
        'Añadirlo al form
        Me.Controls.Add(_MiDGView1)
        '
        'Construir el segundo DGV
        _MiDGView2.Dock = DockStyle.Right
        _MiDGView2.ColumnCount = 4
        _MiDGView2.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
        _MiDGView2.Columns(0).HeaderText = "Caso B"
        Me.Controls.Add(_MiDGView2)
        '
        'La ventana (aspecto)
        '
        'Ajustar el ancho del form
        Me.Width = Me._MiDGView1.Width + Me._MiDGView2.Width + 25
        'Ponerle titulo
        Me.Text = "Pep/Rafa DataGridView"
    End Sub
End Class

'
' Nuestra personalizacion para MiDGView 
'---------------------------------------------------------------
'
Public Class MiDGView
    Inherits DataGridView       'Heredar del DataGridView
    '
    'Prepocesar mensajes
    Public Overrides Function PreProcessMessage( _
                ByRef msg As System.Windows.Forms.Message) As Boolean
 
        'Si es 'KeyDown' y 'Enter'
        If msg.Msg = 257 And msg.WParam.ToInt32 = 13 Then
            Dim MiCol As Integer = 0
            Dim MiFil As Integer = Me.CurrentCell.RowIndex - 1
            'Si noSalimos del limite
            If Me.CurrentCell.ColumnIndex < Me.ColumnCount - 1 Then
                'Siguiente columna
                MiCol = Me.CurrentCell.ColumnIndex + 1
            End If
            'Posicionar columna
            If MiFil > -1 Then Me.CurrentCell = Me(MiCol, MiFil)
        End If
        Return MyBase.PreProcessMessage(msg)
    End Function
End Class
 
'
' Nuestra personalizacion para DGVPlus 
'---------------------------------------------------------------
'
Public Class DgvPlus
    Inherits DataGridView   'Heredar del DataGridView
 
    '
    'en el 'processDialogKey'... cuando estamos en edicion
    Protected Overrides Function ProcessDialogKey( _
                ByVal keyData As System.Windows.Forms.Keys) As Boolean
 
        If keyData = Keys.Enter Then                'Si es 'enter'
            SendKeys.Send(Chr(Keys.Tab))            'Enviar un 'Tab'
            Return True                             'Marcar como procesado
        Else                                        'en caso contrario
            Return MyBase.ProcessDialogKey(keyData) 'devolver KeyData
        End If
    End Function
    '
    ' en 'OnKeyDown'... cuando no estamos en edicion
    Protected Overrides Sub OnKeyDown( _
                ByVal e As System.Windows.Forms.KeyEventArgs)
        If e.KeyData = Keys.Enter Then              'Si es 'enter'
            SendKeys.Send(Chr(Keys.Tab))            'Enviar un 'Tab'
        Else
            MyBase.OnKeyDown(e)                     'Devolver el KeyEventArgs
        End If
    End Sub
End Class

2 comentarios:

  1. este codigo fue sacado del guille si nome equivoco

    ResponderEliminar
  2. efectivamente por ahi me lo encontre hacia tiempo, los son Autores: Pep Lluis y Rafa Vargas

    ResponderEliminar