Introducción
Cuando se desarrolla pantallas de captura de datos por lo general una característica deseable implica que no se pierda los datos cargados cuando se navega a otro sitio a buscar información y se vuelve.
Lamentablemente asp.net no conserva de forma automática el estado de esta información ingresada, por esa razón seremos nosotros quienes mediante código que volquemos la info ingresada para no perderla y facilitar al usuario al operación con la aplicación.
En el ejemplo planteado se cuenta con una lista de productos, con la posibilidad de ingresa una cantidad y opciones provistas para completar la operación.
Mantener el estado de los datos ingresados
Si bien esta funcionalidad es muy similar a la implementada para mantener el estado de los check, cuenta con algunas diferencias que hay que remarcar.
En este caso se conserva algo mas de información que una simple estado de true/false, es por eso que se crea una clase para mantener los datos que son útiles.
internal class ProductInfo { public int Id { get; set; } public int Amount { get; set; } public int Shipper { get; set; } }
Es desde y hacia esta clase que se realizaran las conversiones.
El mantener la información consta de varios pasos:
- se recuperan del gridview solo aquellas rows en donde se ingresara una cantidad y un medio de envió. Se arma en este caso una entidad ProductInfo representativa de los datos que se quiere conservar
- se recupera la información previamente registrada en la session
- se cruzan las listas para quitar las que están en la pagina actual
- se ingresa la nueva información para conservar en session
public static void KeepProductInfo(GridView grid) { // // se obtienen la lista de producto con informacion proporcionada por el usuario // var listProd = from item in grid.Rows.Cast<GridViewRow>() let amount = ((TextBox)item.FindControl("txtAmount")).Text let shipper = ((DropDownList)item.FindControl("ddlShippers")).SelectedValue where !(string.IsNullOrEmpty(amount) || shipper == "0") select new ProductInfo() { Id = Convert.ToInt32(grid.DataKeys[item.RowIndex].Value), Amount= Convert.ToInt32(amount), Shipper = Convert.ToInt32(shipper) }; // // se recupera de session la lista de seleccionados previamente // List<ProductInfo> prodInfo = HttpContext.Current.Session["ProdInfo"] as List<ProductInfo>; if (prodInfo == null) prodInfo = new List<ProductInfo>(); // // se cruzan todos los ingresados en la pagina actual, con los previamente conservados // en Session, devolviendo solo aquellos donde no hay coincidencia // prodInfo = (from item in prodInfo join item2 in listProd on item.Id equals item2.Id into g where !g.Any() select item).ToList(); // // se agregan la actualizacion realizada por el usuario // prodInfo.AddRange(listProd); HttpContext.Current.Session["ProdInfo"] = prodInfo; }
Por supuesto esta misma técnica puede ser usada para conservar cualquier tipo de dato de cualquier pantalla quiere se quiera evitar perder lo ingresado, se podría haber mantenido la info de textbox simple, o de un checkboxlist, combos, etc.
En este caso se uso un gridview porque es un objeto representativo de información compleja para procesar.
Recuperar la info de los datos conservados en session
La acción de recuperar se podría resumir en tres paso
- recuperar la información de session
- cruzar las row del gridview de la pagina actual con la lista de productos existente
- volcar las coincidencias en los controles textbox y dropdownlist
public static void RestoreProductInfo(GridView grid) { List<ProductInfo> prodInfo = HttpContext.Current.Session["ProdInfo"] as List<ProductInfo>; if (prodInfo == null) return; // // se comparan los registros de la pagina del grid con los recuperados de la Session // los coincidentes se devuelven para ser seleccionados // var result = (from item in grid.Rows.Cast<GridViewRow>() join item2 in prodInfo on Convert.ToInt32(grid.DataKeys[item.RowIndex].Value) equals item2.Id into g where g.Any() select new { gridrow = item, prodonfo = g.First() }).ToList(); // // se recorre cada item para asignar la informacion // result.ForEach(x => { ((TextBox)x.gridrow.FindControl("txtAmount")).Text = Convert.ToString(x.prodonfo.Amount); ((DropDownList)x.gridrow.FindControl("ddlShippers")).SelectedValue = Convert.ToString(x.prodonfo.Shipper); }); }
Uso de la funcionalidad implementada
Si bien al momento de conservar los datos ante un paginado se contaba con eventos concretos pre y post para llevar la acción de conservar o recuperar los datos, en este caso también se deberá hallar momentos equivalentes para los cuales volcar los datos.
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { LoadGridProducts(); // // lusgo de cargar el grid se asigna la info que el usuario habia ingresado // ProductsManager.RestoreProductInfo(gvProducts); } } private void LoadGridProducts() { gvProducts.DataSource = NorthwindData.GetAllProducts(); gvProducts.DataBind(); } protected void gvProducts_SelectedIndexChanging(object sender, GridViewSelectEventArgs e) { // // se persiste la informacion ingresada por el usuario // ProductsManager.KeepProductInfo((GridView)sender); // // se recupera el producto seleccionado // int productId= Convert.ToInt32(gvProducts.DataKeys[e.NewSelectedIndex].Value); Response.Redirect(string.Format("ProductDetails.aspx?productId={0}", productId)); }
Tanto en la carga del formulario, como al momento de seleccionar unos de los ítems del grid es que se invocaran la funcionalidad que interactúa con el medio que conserva los datos
Código
El ejemplo ha sido implementado con VS2008 y hace uso de una base de datos Sql Compact
[C#]
|
[C# Skydrive]
|