En el caso de que se encuentren con aplicaciones en las cuales haya un exceso de dato en los controles desplegables, una posible solución es paginar dicho control al estilo de un grid con las opciones de "Primera", "Anterior", "Siguiente" y "Última". Én este artículo muestro como se puede llegar a paginar dichos controles.
Definición del control:
Lo primero será definir el control derivado a partir del DropDownList genérico que estamos acostumbrados a usar.
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Collections;
using System.Data;
namespace WebControlLibrary
{
public class DDLPaginado : DropDownList
{
//Member to hold PagedDataSource
private PagedDataSource pds;
//flag variable to indicate if we should go to the last page
private bool goToLastPage=false;
/// <summary>
/// DataSource
/// </summary>
public override object DataSource
{
get
{
// Nos aseguramos que el PageddataSource ha sido creado
EnsureDataSource();
return pds;
}
set
{
// Si el DataSource es un DataReader no podemos usar este control porque
// no nos indica el nmero de elementos.
if(value is IDataReader)
throw new ArgumentException("DataReader isn't supported as data source","DataSource");
// El DataSource debe ser un DataTable, un DataView o un IEnumerable.
if(!((value is DataTable) || (value is DataView) || (value is IEnumerable)))
throw new ArgumentException("Data source not supported","DataSource");
// Nos aseguramos que el PageddataSource ha sido creado
EnsureDataSource();
// En caso de que el DataSource sea DataTable usamos DefaultView(DataView).
if(value is DataTable)
pds.DataSource =((DataTable)value).DefaultView;
// Si el DataSource es un DataView lo usamos directamente.
if(value is DataView)
pds.DataSource =(DataView)value;
// Si el DataSource es un IEnumerable lo usamos directamente.
if(value is IEnumerable)
pds.DataSource=(IEnumerable)value;
// Se asigna mediante la funcin de la clase base DataSource
base.DataSource =pds;
}
}
/// <summary>
/// "Page index" se usa en la paginacin.
/// </summary>
public int CurrentPageIndex
{
get
{
object o=ViewState[this.UniqueID + "CurrentPageIndex"];
return(o==null)? 0 : (int)o;
}
set
{
ViewState[this.UniqueID + "CurrentPageIndex"]=value;
}
}
/// <summary>
/// Mtodo para incrementar el "Page index".
/// </summary>
public void GoToNextPage()
{
EnsureDataSource();
if(!pds.IsLastPage)
CurrentPageIndex++;
}
/// <summary>
/// Mtodo para decrementar el "Page index".
/// </summary>
public void GoToPreviousPage()
{
EnsureDataSource();
if(CurrentPageIndex > 0)
CurrentPageIndex--;
}
/// <summary>
/// Mtodo para acceder a la primera pgina del DDL.
/// </summary>
public void GoToFirstPage()
{
CurrentPageIndex = 0;
}
/// <summary>
/// Mtodo para acceder a la ltima pgina del DDL.
/// </summary>
public void GoToLastPage()
{
goToLastPage = true;
}
/// <summary>
/// Nmero de elementos por pgina.
/// </summary>
public int PageSize
{
get
{
EnsureDataSource();
return pds.PageSize;
}
set
{
//El nmero de elementos no puede ser menor de 1.
if(value < 1 )
throw new ArgumentException("El nmero de elementos no puede ser menor de 1.");
EnsureDataSource();
pds.PageSize = value;
}
}
/// <summary>
/// Mtodo para asegurarnos que el PagedDataSource ha sido creado.
/// </summary>
private void EnsureDataSource()
{
if(pds ==null)
{
pds=new PagedDataSource();
pds.AllowPaging =true;
pds.PageSize = 10;
}
}
protected override void OnDataBinding(System.EventArgs e)
{
EnsureDataSource();
// Se cuenta el nmero mximo de pginas existentes.
// Slo se puede usar si existe DataSource.
if(base.DataSource == null)
throw new ArgumentException("DataSource no puede estar vaco.");
int countableindex;
try
{
// ndice es el DataSourceCount por PageSize
countableindex=(int)(pds.DataSourceCount / pds.PageSize);
// Si el mdulo es 0, el ndice se debe decrementar en 1
if(pds.DataSourceCount % pds.PageCount == 0)
{
countableindex--;
}
}
catch(Exception ex)
{
countableindex=0;
}
// Se verifica que el ndice no sobrepasa la ltima pgina existente
if(CurrentPageIndex > countableindex || goToLastPage == true)
{
pds.CurrentPageIndex = countableindex;
// Se asigna la propiedad CurrentPageIndex para que refleje el ndice correcto
CurrentPageIndex=countableindex;
}
else
{
// El ndice toma el valor del CurrentPageIndex
pds.CurrentPageIndex = CurrentPageIndex;
}
// Llamada de la clase base del OnDataBinding
base.OnDataBinding(e);
}
}
}
Uso del control:
El control funcionará igual que otros controles a los cuales se les asocia datos mediante un DataSource (data-bound control in ASP.NET).
PARTE VISUAL (.ASCX)
<asp:Button ID="btnPrimera" Runat=server Text="Primera" />
<asp:Button ID="btnAnterior" Runat=server Text="Anterior" />
<asp:Button ID="btnSiguiente" Runat=server Text="Siguiente" />
<asp:Button ID="btnUltima" Runat=server Text="Última" />
<br/>
<cc1:DDLPaginado id=DDLPaginado1 runat="server" PageSize="10"></cc1:DDLPaginado>
CÓDIGO (.ASPX.CS)
private void Page_Load(object sender, System.EventArgs e)
{
if(!Page.IsPostBack)
{
BindDDL();
}
}
//Test data
private void BindDDL()
{
SortedList sl=new SortedList();
for(int i=1;i<51;i++)
sl.Add(i,i);
PagedDDL1.DataSource = sl;
PagedDDL1.DataValueField ="Value";
PagedDDL1.DataTextField ="Key";
PagedDDL1.DataBind();
}
private void btnFirst_Click(object sender, System.EventArgs e)
{
PagedDDL1.GoToFirstPage();
BindDDL();
}
private void btnPrevious_Click(object sender, System.EventArgs e)
{
PagedDDL1.GoToPreviousPage();
BindDDL();
}
private void btnNext_Click(object sender, System.EventArgs e)
{
PagedDDL1.GoToNextPage();
BindDDL();
}
private void btnLast_Click(object sender, System.EventArgs e)
{
PagedDDL1.GoToLastPage();
BindDDL();
}
Con este código ya estaría funcionando el DropdownList con paginación en vuestra aplicación.