listas-genericas-delegate

Aqui voy a dejar una solucion para un problema que se nos puede presentar cuando queremos “marcar” una lista generica en base a otra lista.

Ejemplo: Tengo una lista de todas las Sucursales y tengo otra en la cual me informan las que se van a cerrar. Debo listar todas las Sucursales en una grilla y dejar marcadas aquellas que se van a cerrar.

Una solucion tradicion seria un foreach para recorrer ambas listas e ir uno por uno de los elementos. Como muestra este codigo:

//lista total de sucursales
List<Sucursal> listaSucursales = new List<Sucursal>();
//lista sucursales cerradas
List<Sucursal> listaSucursalesCerradas = new List<Sucursal>();

//metodo tradicional con foreach
foreach(Sucursal suc in listaSucursales)
{
	foreach(Sucursal sucCerrada in listaSucursalesCerradas)
	{
		//si encuentro el codigo de la sucursal en la lista de cerradas
		//la marco y salgo del foreach y sigo con la siguiente
		if (suc.Codigo == sucCerrada.Codigo)
		{
			suc.Cerrada = true;
			break;
		}
	}
}

Con Generics podemos usar una potencialidad que tiene al manejar un “delegate” como metodo para la busqueda interna de elementos en la lista.

Pero vamos por parte. Primero tendremos una pagina web con la siguiente grilla:

	
<asp:GridView ID="gvSucursales" runat="server" AutoGenerateColumns="False"  AllowPaging="false" 
    AllowSorting="false" OnRowDataBound="gvSucursales_RowDataBound" Width="300" >
        <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
        <RowStyle BackColor="#EFF3FB" />
        <HeaderStyle BackColor="#D77E1E" Font-Bold="true" ForeColor="White" HorizontalAlign="center" />
        <PagerStyle BackColor="White" ForeColor="#003366" HorizontalAlign="Right" />
        <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" />
        <Columns>
            <asp:TemplateField>
                <HeaderTemplate>
                    <asp:CheckBox ID="chkTodos" runat="server" Text="" />
                </HeaderTemplate>
                <ItemTemplate>
                    <asp:CheckBox ID="chkSuc" runat="server" AutoPostBack="true" />
                </ItemTemplate>
                <ItemStyle HorizontalAlign="Center" />
            </asp:TemplateField>
            <asp:BoundField DataField="Codigo" HeaderText="Codigo" ItemStyle-HorizontalAlign="Center" />
            <asp:BoundField DataField="Descripcion" HeaderText="Sucursal" ItemStyle-HorizontalAlign="Left" />                                
        </Columns>
        <AlternatingRowStyle BackColor="GreenYellow" ForeColor="Blue" />
    </asp:GridView>

En esta grilla listaremos TODAS las sucursales y marcaremos las que seran cerradas. Para esto creamos una entidad llamada “Sucursal” con las siguientes propiedades:

	
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;

/// &lt;summary&gt;
/// Summary description for Sucursal
/// &lt;/summary&gt;
public class Sucursal
{
    private string codigo;
    private string descripcion;
    private bool cerrada;

	public Sucursal()
	{
		//
		// TODO: Add constructor logic here
        //
        codigo = string.Empty;
        descripcion = string.Empty;
        cerrada = false;
    }
	public string Codigo
    {
        get
        {
            return codigo;
        }
        set
        {
            codigo = value;
        }
    }

    public string Descripcion
    {
        get
        {
            return descripcion;
        }
        set
        {
            descripcion = value;
        }
    }

    public bool Cerrada
    {
        get
        {
            return cerrada;
        }
        set
        {
            cerrada = value;
        }
    }
	
}

Segundo, crearemos dos metodos que simularan la carga de las dos listas en cuestion: Todas las sucursales y las cerradas:

	
//lista total de sucursales
    List<Sucursal> listaSucursales = new List<Sucursal>();
    //lista sucursales cerradas
    List<Sucursal> listaSucursalesCerradas = new List<Sucursal>();
    List<Sucursal> results = new List<Sucursal>();
    Sucursal sucursal;
    bool retorno = false;

    private void CargaSucursales()
    {
        sucursal = new Sucursal();
        sucursal.Codigo = "100";
        sucursal.Descripcion = "Arica";
        listaSucursales.Add(sucursal);

        sucursal = new Sucursal();
        sucursal.Codigo = "101";
        sucursal.Descripcion = "Iquique";
        listaSucursales.Add(sucursal);

        sucursal = new Sucursal();
        sucursal.Codigo = "200";
        sucursal.Descripcion = "Antofagasta";
        listaSucursales.Add(sucursal);

        sucursal = new Sucursal();
        sucursal.Codigo = "201";
        sucursal.Descripcion = "Calama";
        listaSucursales.Add(sucursal);

        sucursal = new Sucursal();
        sucursal.Codigo = "202";
        sucursal.Descripcion = "Tocopilla";
        listaSucursales.Add(sucursal);

        sucursal = new Sucursal();
        sucursal.Codigo = "203";
        sucursal.Descripcion = "Mejillones";
        listaSucursales.Add(sucursal);

        sucursal = new Sucursal();
        sucursal.Codigo = "300";
        sucursal.Descripcion = "Copiapo";
        listaSucursales.Add(sucursal);

        sucursal = new Sucursal();
        sucursal.Codigo = "301";
        sucursal.Descripcion = "El Salvador";
        listaSucursales.Add(sucursal);

        sucursal = new Sucursal();
        sucursal.Codigo = "302";
        sucursal.Descripcion = "Vallenar";
        listaSucursales.Add(sucursal);

        sucursal = new Sucursal();
        sucursal.Codigo = "400";
        sucursal.Descripcion = "La Serena";
        listaSucursales.Add(sucursal);

        sucursal = new Sucursal();
        sucursal.Codigo = "401";
        sucursal.Descripcion = "Vicuña";
        listaSucursales.Add(sucursal);

        sucursal = new Sucursal();
        sucursal.Codigo = "402";
        sucursal.Descripcion = "Ovalle";
        listaSucursales.Add(sucursal);

        sucursal = new Sucursal();
        sucursal.Codigo = "403";
        sucursal.Descripcion = "Illapel";
        listaSucursales.Add(sucursal);

        sucursal = new Sucursal();
        sucursal.Codigo = "404";
        sucursal.Descripcion = "Los Vilos";
        listaSucursales.Add(sucursal);

    }

    private void CargaSucursalesCerradas()
    {
        sucursal = new Sucursal();
        sucursal.Codigo = "202";
        sucursal.Descripcion = "Tocopilla";
        sucursal.Cerrada = true;
        listaSucursalesCerradas.Add(sucursal);
        
        sucursal = new Sucursal();
        sucursal.Codigo = "301";
        sucursal.Descripcion = "El Salvador";
        sucursal.Cerrada = true;
        listaSucursalesCerradas.Add(sucursal);
        
        sucursal = new Sucursal();
        sucursal.Codigo = "302";
        sucursal.Descripcion = "Vallenar";
        sucursal.Cerrada = true;
        listaSucursalesCerradas.Add(sucursal);

        sucursal = new Sucursal();
        sucursal.Codigo = "400";
        sucursal.Descripcion = "La Serena";
        sucursal.Cerrada = true;
        listaSucursalesCerradas.Add(sucursal);

    }    

Tercero, marcaremos la lista total de Sucursales en base a la segunda lista usando Generics y un Delegate Anonimo:

	
    private void MarcaListas()
    {
        //aqui &quot;cruzo&quot; las dos listas, la primera tiene todas las sucursales
        //y la segunda las sucursales cerradas
        //con este codigo &quot;marco&quot; en la primera lista las sucursales que 
        //estan cerradas la segunda lista
        results = listaSucursales.FindAll(delegate(Sucursal s)
        {
            bool rr = listaSucursalesCerradas.Exists(delegate(Sucursal lasucursal)
            {
                retorno = s.Codigo == lasucursal.Codigo;

                return retorno;
            });
            //marco la sucursal que viene cerrada
            s.Cerrada = retorno;
            return rr;
        });
    }

Para que esto sea visible en nuestra grilla, debemos completar el metodo “gvSucursales_RowDataBound” para refleje en pantalla el cambio:

	
protected void gvSucursales_RowDataBound(object sender, GridViewRowEventArgs e)
    {        
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            Sucursal suc = (Sucursal)e.Row.DataItem;
            CheckBox chk = (CheckBox)e.Row.FindControl(&quot;chkSuc&quot;);
            chk.Checked = suc.Cerrada;
            
        }
    }

Por ultimo, tenemos que ejecutar los metodos de carga y mezcla de listas en nuetro page_load:

	
protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            CargaSucursales();
            CargaSucursalesCerradas();
            MarcaListas();

            gvSucursales.DataSource = listaSucursales;
            gvSucursales.DataBind();
        }
    }

El resultado de la ejecucion de este codigo se veria asi:

listas-genericas-delegate-gridview

El codigo completo de la solucion lo pueden bajar de aqui:

ASP.NET Marcar Listas Genericas con Delegate

Espero que les ayude en sus trabajos.

TYDW.-