lunes, 10 de octubre de 2011

[GridView] Eventos de controles contenidos en el GridView (2/2)

 

Introducción

Este artículo representa una continuación de:

[GridView] Eventos de controles contenidos en el GridView (1/2)

en donde se planteara un ejemplo práctico del uso de eventos en controles contenidos en el gridview

El ejemplo representa la edición de un empleado a quien se le asigna determinadas prendas de vestir por parte de la empresa. Lo importante es que debe registrarse la fecha en que fue asigna esa indumentaria.

Un punto a que no debe dejarse pasar por alto es que la selección de la prenda asignada no debe actualizar la tabla en al db directamente, la información se encontrara registrada en memoria, cuando el usuario confirme los cambios mediante el botón de aceptar será el momento en que  toda la información, incluida las indumentarias, impactara en la base de datos.

Diseño de objetos

Las entidades estarán representadas mediante el siguiente diagrama

La entidad Empleado se relaciona con las listas de estudios he indumentarias que tiene asociada. Es por esta razón que en la capa de Acceso a datos se recuperan estas relaciones cuando se obtiene una entidad.

Esta información relacionada al empleado será utilizada en las acciones de actualización cuando se efectúen las acciones en la presentación, esto se llevara a cabo mediante el “EmpleadoManager”

 

Actualizar Entidad

Una técnica bastante utilizada para encapsular la funcionalidad de entidades en memoria cuando se debe conservar la información dentro del objeto Session, consiste en crear una clase que aplique el patrón singleton.

Este patrón usar el objeto Session para contener su información entre request.

Se puede ver en este caso la implementación en la clase “EmpleadoManager”

/// <summary>
/// El objetivo de esta clase es generar una abstraccion al uso de la Session para administrar la entidad del empleado
/// </summary>
public class EmpleadoManager
{
    private EmpleadoEntity empleado;

    private EmpleadoManager()
    {
        empleado = new EmpleadoEntity();
    }

    public static EmpleadoManager Instance()
    {
        if(HttpContext.Current.Session["empleado"] == null)
        {
            HttpContext.Current.Session["empleado"] = new EmpleadoManager();
        }

        return (EmpleadoManager)HttpContext.Current.Session["empleado"];
    }

    public static void NuevoEmpleado()
    {
        HttpContext.Current.Session.Remove("empleado");
    }

    public EmpleadoEntity Empleado
    {
        get { return empleado; }
        set { empleado = value; }
    }


    public void IndumentariaAsignar(int idIndumentaria)
    {
        if (HttpContext.Current.Session["empleado"] == null)
            return;
        
        //Se recupera la entidad lista de la session
        EmpleadoManager empleadoManager =(EmpleadoManager)HttpContext.Current.Session["empleado"];

        List<IndumentariaEntity> indumentaria = empleadoManager.Empleado.IndumentariaAsignada;

        //se recupera la entidad de la lista y se actualiza la fecha de asignacion
        if (indumentaria.Exists(x => x.IdIndumentaria == idIndumentaria))
        {
            indumentaria.Where(x => x.IdIndumentaria == idIndumentaria)
                                            .First()
                                            .FechaAsignacion = DateTime.Now;
        }
        else
        {
            indumentaria.Add(new IndumentariaEntity()
            {
                 IdIndumentaria = idIndumentaria,
                 FechaAsignacion = DateTime.Now
            });
        }

    }

    public void IndumentariaDesasignar(int idIndumentaria)
    {
        if (HttpContext.Current.Session["empleado"] == null)
            return;

        //Se recupera la entidad lista de la session
        EmpleadoManager empleadoManager = (EmpleadoManager)HttpContext.Current.Session["empleado"];

        List<IndumentariaEntity> indumentaria = empleadoManager.Empleado.IndumentariaAsignada;

        //se recupera la entidad de la lista y se actualiza la fecha de asignacion
        if (indumentaria.Exists(x => x.IdIndumentaria == idIndumentaria))
        {
            indumentaria.RemoveAll(x => x.IdIndumentaria == idIndumentaria);                           
        }

    }


}

La utilización desde la pagina es muy simple

protected void checkIndumentaria_CheckedChanged(object sender, EventArgs e)
{
    CheckBox checkBox = sender as CheckBox;

    //NamingContainer devuelve el objeto donde esta contenidos el checkbox
    //en este caso se trata de una row del gridview
    GridViewRow row = checkBox.NamingContainer as GridViewRow;
    
    //conociendo la row se puede obtener el id de la entidad que se esta seleccionando
    int idindumentaria = Convert.ToInt32(gvIndumentaria.DataKeys[row.RowIndex].Value);

    if (checkBox.Checked)
        EmpleadoManager.Instance().IndumentariaAsignar(idindumentaria);
    else
        EmpleadoManager.Instance().IndumentariaDesasignar(idindumentaria);


    AsignarIndumentaria(EmpleadoManager.Instance().Empleado);

}

Es en este punto donde se aplica la técnica que permite recuperar la fila seleccionada al marcar el checkbox contendió en el gridview.

 

Código


El ejemplo se desarrollo con VS 2008, y base de datos Sql Server Express 2008 R2

[C#]
[C# SkyDrive]

7 comentarios:

  1. Hola Leandro. Estaba revisando tú blog y justamente me tope con algo que vengo investigando hace un tiempo, como pasar una clase, entre request sin tener que buscarla cada vez, es decir, lo que tienes en Actualizar Empleado. Una preguntica, ¿Por que no funciona directamente la variable de sessión, sin tener que hacer todo lo que hiciste??? algo como: Empleado empleado = (empleado)Session["empleado"]..
    Gracias!!

    ResponderEliminar
  2. hola Pierina Joplin

    porque esa es una forma de encapsular la complejidad y logica del codigo

    si lo haces como mencionas tendrias desperdigado por todos lados ese codigo, un cambio simple impactaria en miles de lugares

    en este caso es una aplicacion pequeña, pero imagina un desarollo de 100 paginas web, pasando informacion por todos lados, sino lo encapsulas y piensas en reutilzias se vuelve un descontrol


    lo que planteas si se puede usar, pero esta tecnica apunta a abstraerse de la session, o como se implemente
    es mas si mañana no quiero usar un Session, sino aplciar un objeto de cache, una db, el cambio es bien simple toco la clase y el resto del sitio se mentien intacto ni se entera.

    ese es el poder de encapsular la logica

    saludos

    ResponderEliminar
  3. Hola, otro comentario con respecto a esto, existe alguna forma de verificar si el objeto que está en la variable de session ha sido modificado, sin necesidad de buscarlo? La respuesta me parece obvia, pero me gustaría saber tú opinión, gracias!

    ResponderEliminar
  4. hola Pierina Joplin

    no entendi del todo el planteo

    pero recuerda que la Session esta del lado del server, solo cuando haces un postbacvk ante algun evento es que dispones del mismo y puedes usarlo

    el detectar algun cambio en el servidor no implcia que puedas notificar esto al browser del cliente

    saludos

    ResponderEliminar
  5. Hola Leandro... Ayudame en Algo Por Favor... quiero importar columnas y sus respectivas informaciones en un GridView en ASP.NET C# por ejemplo.. quiero llamar las columnas A,B,X,Y,Z... ayudame porfavor.. de antemano Gracias..

    ResponderEliminar
  6. hola Gary

    la verdad no entendi el planteo, como es eso de importar columnas ?

    puedes definir columnas en tiempo de diseño y asignar el DataField
    para indicar con que columna del origen de datos mapea

    pero para esto funcione debes definir en el grid el AutoGenerateColumns = false

    saludos

    ResponderEliminar