jueves, 10 de diciembre de 2009

[DataGridView] Parte 2 – Edición de celda con form PopUp para la selección de ítem - KeyDown

 

El objetivo del articulo es demostrar como en la edición de la celda se puede lanzar un formulario de búsqueda para la selección de un ítem determinado, y a retorno del mismo completar la información de la fila en edición con la selección del formulario.

Para esta operación se hace uso de propiedades, y clases las cuales permitirán desacoplar ambas grilla, tanto la que originalmente mantiene la lista de productos seleccionados, como la que se despliega y permite la elección de un ítem determinado.

En el formulario cuyo objetico será llevar la lista de ítems elegidos por el usuario se dispone de siguiente código.

private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
    DataGridViewTextBoxEditingControl dText = (DataGridViewTextBoxEditingControl)e.Control;

    dText.KeyDown -= new KeyEventHandler(dText_KeyDown);
    dText.KeyDown += new KeyEventHandler(dText_KeyDown);
}

void dText_KeyDown(object sender, KeyEventArgs e)
{
    int rowIndex = ((System.Windows.Forms.DataGridViewTextBoxEditingControl)(sender)).EditingControlRowIndex;

    if (e.Alt && e.KeyCode == Keys.D)
    {
        frmSeleccionarProducto form = new frmSeleccionarProducto();

        form.ShowDialog();

        Producto productoSeleccionado = form.ProductSelected;

        DataGridViewRow row = dataGridView1.Rows[rowIndex];
        row.Cells["IdProducto"].Value = productoSeleccionado.IdProducto;
        row.Cells["Descripcion"].Value = productoSeleccionado.Descripcion;
        row.Cells["precio"].Value = productoSeleccionado.Precio;

        dataGridView1.EndEdit();
    }  
}

Como se observa mucha de la funcionalidad tiene que ver con la asignación de los eventos que permitirán capturar la pulsación de la teclas definidas para que se visualice el formulario de PopUp.

En este caso si bien es posible utilizar cualquier tecla, se decidió que la combinación de Alt + D seria la adecuada, pero podría seleccionar la que sea necesario.

Como se observa si se detecta la pulsación de la tecla, se crea una instancia del formulario y se muestra en formulario modal. Al cierre del mismo se captura la propiedad con el ítem elegido y se carga en la grilla.

El formulario que se desplegara tiene un código muy simple en donde simplemente al hacer dobleclick en una de sus filas, la marcara como seleccionada y cerrar el formulario.

private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
    DataGridViewRow row = dataGridView1.SelectedRows[0];

    this.ProductSelected = new Producto()
    {
        IdProducto = Convert.ToInt32(row.Cells["IdProducto"].Value),
        Descripcion = Convert.ToString(row.Cells["Descripcion"].Value),
        Precio = Convert.ToDecimal(row.Cells["precio"].Value),
    };

    this.Close();
}
[C#]
[VB.NET]

8 comentarios:

  1. Hola Leandro,

    esta parte no la has etiquetado como DataGridView y al buscar solo aparecen las otras tres partes.

    Gracias y un saludo.

    Antonio Tobajas.

    ResponderEliminar
  2. hola
    gracias por el comentario

    si tienes razon olvide de agregar etiquetas a este articulo, pero ya esta solucionado las he agregado

    saludos

    ResponderEliminar
  3. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  4. Hola Leandro,

    ¿por qué en la linea 5 quitas el manejador del evento y en la linea 6 vuelves a añadrilo?.

    Muchas gracias. Antonio

    ResponderEliminar
  5. hola

    la idea de esa lineas es asegurar que la celda que toma el control, tenga asignado el evento de forma correcta.
    Cuando trabajas con objetos lo que usas son las referencias de los mismos, por lo tanto si editas una celda y asignas el evento, luego si vuelves a editar estarias asignando nuevamente el mismo evento, o sea tendras dos veces el mismo evento para esa celda lo cual no es correcto.

    La verdad no lo verifique del todo, pero puedes verificarlo si quieres, pon un breakpoint en la linea 5, cuando se detecta pasa el puntero del mouse por sobre el evento Keypress, veras que la primera oportunidad tendrias que estar en null o nothing para esa celda, pero si dejas de editar la celda y vuelves a la misam seguramente cuando se detecta en el break y pases el mpouse esta tendra el evento asignado de la pasada anterior.

    Esto sucede porque con los objetos se usan sus referencias, puede tomasrlas en variables o dejarlas pero mientras este viva una de las instancias conservara su contenido y asignaciones.

    Bueno espero la explicacion sea de utildiad

    saludos

    ResponderEliminar
  6. Hola Leandro,

    entendido. He intentado ver con un punto de ruptura el contenido del evento KeyDown y no consigo saber dónde está.
    He descargado tu código en C# y el punto de ruptura lo hago en la fila en negrita:

    private void dataGridView_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
    {
    DataGridViewTextBoxEditingControl dText = (DataGridViewTextBoxEditingControl)e.Control;

    dText.KeyDown -= new KeyEventHandler(dText_KeyDown);
    dText.KeyDown += new KeyEventHandler(dText_KeyDown);
    }

    Pero para ver como quita y añade el manejador no veo el evento KeyDown, ¿dónde puedo localizarlo?.

    Saludos.

    ResponderEliminar
  7. hola

    El breakpoint esta correcto donde lo has puesto, resulta que para ver el efecto cuando se detenga el codigo en ese punto, pasa el puntero del maouse por sobre "KeyDown"
    veras que la primera vez que ingresa una celda nueva esta esta en null
    pero cuando se edita una celda que anteriormente habia pasado por alli este tiene una instancia o handler asignado previamente, que quedo de la entrada anterior

    Esta es la diferencia ante la edicion de una celda nueva y una que fue editada previamente, el tiene el vento con un handler no nulo, el -= lo que ahces es quitar la asignaciuon anterior y el += agregar una nueva.

    saludos

    ResponderEliminar
  8. Buenas Leandro, sobre lo de agregar y quitar el handler todo OK, pero me queda la duda sobre lo breakpoint, porque paso el puntero del mouse como dices por "KeyDown" pero no noto nada, incluso le he agregado una inspección rápida pero sigo sin notar nada.

    ResponderEliminar