martes, 1 de junio de 2010

[DataGridView] – Texto Celdas en Mayúscula

 

Introducción

En algunos casos es necesario que la entrada de datos sea siempre en mayúscula, lograr esto en un control Textbox es relativamente simple, ya que se dispone del evento KeyPress para detectar y convertir el valor ingresado.

Pero que sucede si esto mismo se quiere aplicar a las celdas de un DataGridView, bien este articulo demuestra como poder lograrlo.

Usando el evento EditingControlShowing

En el ejemplo se hará uso del evento que permitirá detecta cuando una celda entra en modo de edición.

Dentro del evento EditingControlShowing, se detecta si la columna que entro en modo de edición corresponde a la que se quiere controlar. En este ejemplo solo la columna “Descripcion” será afectada con el control en el input de datos.

Es necesario remarcar que al momento de adjunta el evento KeyPress al objeto e.Control, (que ha sido casteado a DataGridViewTextBoxEditingControl, para su correcta utilización), el handler del evento se aplicaría a todas las celdas de este mismo tipo. También a las de las columnas que no se quiere aplicar el control de mayúsculas, en este caso la de  “Cuenta”.

Es por eso que en el evento KeyPress también se control la columna que esta activa en ese momento.

El handler del evento queda adjunto aun cuando se sale de modo edición.

La utilización de la primer línea que quita el hadler al entrar en edición:

dText.KeyPress -= new KeyPressEventHandler(dText_KeyPress);

Solo sirve para que se adjunte un único evento, ya que sino estuviera se adjuntarían una detrás de otro produciéndose múltiples llamadas al evento KeyPress.

[C#]

private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
    int columnIndex = dataGridView1.CurrentCell.ColumnIndex;

    if (dataGridView1.Columns[columnIndex].Name == "Descripcion")
    {
        DataGridViewTextBoxEditingControl dText = (DataGridViewTextBoxEditingControl)e.Control;

        dText.KeyPress -= new KeyPressEventHandler(dText_KeyPress); 
        dText.KeyPress += new KeyPressEventHandler(dText_KeyPress);
    }
}

void dText_KeyPress(object sender, KeyPressEventArgs e)
{
    int columnIndex = dataGridView1.CurrentCell.ColumnIndex;

    if (dataGridView1.Columns[columnIndex].Name == "Descripcion")
    {
        e.KeyChar = char.ToUpper(e.KeyChar);
    }
}

[VB.NET]

 

Private Sub dataGridView1_EditingControlShowing(ByVal sender As Object, ByVal e As DataGridViewEditingControlShowingEventArgs)

    Dim columnIndex As Integer = dataGridView1.CurrentCell.ColumnIndex

    If dataGridView1.Columns(columnIndex).Name = "Descripcion" Then

        Dim dText As DataGridViewTextBoxEditingControl = DirectCast(e.Control, DataGridViewTextBoxEditingControl)

        RemoveHandler dText.KeyPress, AddressOf dText_KeyPress
        AddHandler dText.KeyPress, AddressOf dText_KeyPress

    End If

End Sub

Private Sub dText_KeyPress(ByVal sender As Object, ByVal e As KeyPressEventArgs)

    Dim columnIndex As Integer = dataGridView1.CurrentCell.ColumnIndex

    If dataGridView1.Columns(columnIndex).Name = "Descripcion" Then

        e.KeyChar = Char.ToUpper(e.KeyChar)

    End If

End Sub

 

[C#]
[VB.NET]

 

Resolución del problema en al asignación del evento

El problema comentado anteriormente podrías resolverse fácilmente con solo declarar la variable que contendrá la celda en edición de forma global al evento.

De esta forma se podrías hacer uso del evento que detecta cuando una celda ha dejado de editarse, removiendo el handler del evento.

Ahora el evento KeyPress no controla que columna se esta editando, esto solo se hace cuando se entra o sale del modo edición de la celda.

[C#]

DataGridViewTextBoxEditingControl dText = null;

private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
    int columnIndex = dataGridView1.CurrentCell.ColumnIndex;

    if (dataGridView1.Columns[columnIndex].Name == "Descripcion")
    {
        dText = (DataGridViewTextBoxEditingControl)e.Control;
        
        dText.KeyPress += new KeyPressEventHandler(dText_KeyPress);
    }
}

private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
    int columnIndex = dataGridView1.CurrentCell.ColumnIndex;

    if (dataGridView1.Columns[columnIndex].Name == "Descripcion")
    {
        dText.KeyPress -= new KeyPressEventHandler(dText_KeyPress);
    }
}

void dText_KeyPress(object sender, KeyPressEventArgs e)
{
   e.KeyChar = char.ToUpper(e.KeyChar);
}

[VB.NET]

Private dText As DataGridViewTextBoxEditingControl = Nothing

Private Sub dataGridView1_EditingControlShowing(ByVal sender As Object, ByVal e As DataGridViewEditingControlShowingEventArgs) Handles dataGridView1.EditingControlShowing

    Dim columnIndex As Integer = dataGridView1.CurrentCell.ColumnIndex

    If dataGridView1.Columns(columnIndex).Name = "Descripcion" Then

        dText = DirectCast(e.Control, DataGridViewTextBoxEditingControl)

        AddHandler dText.KeyPress, AddressOf dText_KeyPress

    End If
End Sub

Private Sub dataGridView1_CellEndEdit(ByVal sender As Object, ByVal e As DataGridViewCellEventArgs) Handles dataGridView1.CellEndEdit

    Dim columnIndex As Integer = dataGridView1.CurrentCell.ColumnIndex

    If dataGridView1.Columns(columnIndex).Name = "Descripcion" Then
        RemoveHandler dText.KeyPress, AddressOf dText_KeyPress
    End If

End Sub

Private Sub dText_KeyPress(ByVal sender As Object, ByVal e As KeyPressEventArgs)

    e.KeyChar = Char.ToUpper(e.KeyChar)

End Sub

 

[C#]
[VB.NET]

7 comentarios:

  1. tengo la tarea de agregar registros a un datagridview en C# .. en mi form hay un datagriview y un button , en el load del form creo las columnas

    productos.Columns.Add("ITEM");
    productos.Columns.Add("PRODUCTO");
    productos.Columns.Add("CANTIDAD");
    productos.Columns.Add("PRECIO");



    los registros los ingreso en textbox y los guardo al hacer click en el button pero mi profe me dijo que el campo item se debe aumnetar cada vez que ingreso un numero registro , comienza en uno en el primer registro y cuando ingrese otro seria dos, y asi sucesivamente

    ResponderEliminar
  2. el campo item debe aumentar de uno en uno ... ayudeme por favor

    ResponderEliminar
  3. hola PAOLO

    pero no deberias ingresar el registro en la tabla de la db de forma directa?

    porque si lo ahces podrias definir ese di como autonumerico en el id de la tabla

    a donde a punto es que no uses un control como el grid para insertar alli usa directo la tabla de la db y luego recarga el grid para ver el nuevo dato

    [ADO.NET] – Parte 6 - Ejemplos simples – Campos Auto numéricos (Identity)

    saludos

    ResponderEliminar
  4. Hola Leandro
    En la primera parte de la implementación donde se crea los eventos tengo que poner de esta manera si no me sale error.
    private void dgvClasificacion_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
    {
    int columnIndex = dgvClasificacion.CurrentCell.ColumnIndex;
    if(dgvClasificacion.Columns[columnIndex].Name == "Descripcion")
    {
    DataGridViewTextBoxEditingControl dText = (DataGridViewTextBoxEditingControl)e.Control;
    dText.KeyPress -= new KeyPressEventHandler(dText_KeyPress);
    dText.KeyPress += new KeyPressEventHandler(dText_keyPress);
    }
    }

    private void dText_KeyPress(object sender, KeyPressEventArgs e)
    {
    throw new NotImplementedException();
    }

    private void dText_keyPress(object sender, KeyPressEventArgs e)
    {
    int columnIndex = dgvClasificacion.CurrentCell.ColumnIndex;
    if (dgvClasificacion.Columns[columnIndex].Name == "Descripcion")
    {
    e.KeyChar = char.ToUpper(e.KeyChar);
    }
    }

    ResponderEliminar
  5. Leandro cual de las dos implementaciones es valida por que la primera no me esta funcionando.

    ResponderEliminar