Я нахожусь в проекте WebForms, где необходимо разбить на страницы данные, которые я получаю из хранимой процедуры, я использую VS 2010 Framework 3.5, ASP.NET WebForms и SQL Server 2008.
Это хранимая процедура:
@CantPagina INT, --Amount of registries per each page
@Pagina INT, --Amount of pages
@AsuntoVariable VARCHAR(100), --Search variable
@IdComercio VARCHAR(100), --Search variable
@FechaEnvioDesde DATE, --Search variable
@FechaEnvioHasta DATE, --Search variable
@DescripcionLarga VARCHAR(100), ---Search variable
@Destinatario VARCHAR(100) --Search variable
AS
BEGIN
SET NOCOUNT ON;
DECLARE
@FechaMin DATE = (SELECT CAST(-53690 AS DATETIME)), --Search variable
@FechaMax DATE = GETDATE() --Search variable
--If number of pages is 0 or null, return all data
IF (@CantPagina = 0 OR @CantPagina IS NULL)
BEGIN
SET @CantPagina = 2147483646
END;
IF (@Pagina = 0 OR @Pagina IS NULL)
BEGIN
SET @Pagina = 1
END;
IF(@IdComercio = '-1')
BEGIN
SET @IdComercio = ''
END;
WITH PageNumbers AS
(
SELECT TOP 100 PERCENT
mda.IdComercio, mda.FechaEnvio, tda.DescripcionLarga, mda.Destinatario, mda.AsuntoVariable,
ROW_NUMBER() OVER(ORDER BY mda.FechaEnvio DESC) AS NumFila --Creo columna n + 1
FROM
tm_mda_mail_de_alerta_wcom AS mda
INNER JOIN
tm_tda_tipos_de_alerta_wcom AS tda ON mda.IdTipo = tda.IdTipo
WHERE
mda.AsuntoVariable LIKE '%' + @AsuntoVariable + '%'
AND tda.DescripcionLarga LIKE '%' + @DescripcionLarga + '%'
AND mda.Destinatario LIKE '%' + @Destinatario + '%'
AND mda.FechaEnvio BETWEEN ISNULL(@FechaEnvioDesde, @FechaMin) AND ISNULL(DATEADD(DAY, 1, @FechaEnvioHasta), @FechaMax)
AND CAST(mda.IdComercio AS VARCHAR(20)) LIKE '%' + @IdComercio + '%'
ORDER BY
mda.FechaEnvio DESC)
SELECT *
FROM PageNumbers
WHERE NumFila BETWEEN ((@Pagina - 1) * @CantPagina + 1)
AND (@Pagina * @CantPagina)
END
А бэкэнд выглядит так:
В Page_Load
внутри (!IsPostBack)
:
TraerAlertaCargarGrilla(new WC.Paginacion() { Pagina = PAGINA, RegistrosPorPagina = CANTPAGINA });
А потомЯ вызываю этот метод:
private void TraerAlertaCargarGrilla(WC.Paginacion paginacion)
{
try
{
List<Alerta> alertas = CargarLogEnvioMails(paginacion);
CargarGrillaEnvioMails(alertas);
}
catch (Exception ex)
{
MensajeFront.Mostrar(Page.Title, Resources.Facturacion.Error_Generico_Usuario, Controles_Comunes_wucMensaje.TipoMensaje.Info);
log.Error(String.Format(Resources.Facturacion.LogError, Helper.TraerNombreDelMetodo()), ex);
throw ex;
}
}
Затем я вызываю этот метод:
private List<Alerta> CargarLogEnvioMails(WC.Paginacion paginacion)
{
List<Alerta> logAlertas = new List<Alerta>();
int noFiltrarPorComercio = -1;
try
{
WC.AlertaDTOResp alertaDTOResp = new WC.AlertaDTOResp() { ListaDeAlertas = new WC.ListaDeAlertas() };
WC.AlertaDTOReq alertaDTOReq = new WC.AlertaDTOReq()
{
TipoOperacion = WC.Accion.Consultar,
Operacion = Constantes.Consultas.Alertas.CONSULTA_LOG_ALERTAS,
Paginacion = paginacion,
ListaDeAlertas = new WC.ListaDeAlertas()
{
new WC.AlertaDTO()
{
AsuntoVariable = txtRazon.Text,
IdComercio = txtComercio.Text == String.Empty ? noFiltrarPorComercio : Convert.ToInt32(txtComercio.Text),
FechaDesde = txtFechaDesde.Text == String.Empty ? DateTime.MinValue : Convert.ToDateTime(txtFechaDesde.Text),
FechaHasta = txtFechaHasta.Text == String.Empty ? DateTime.Now : Convert.ToDateTime(txtFechaHasta.Text),
Destinatario = txtDestinatario.Text,
TipoAlerta = new List<WC.TipoAlertaDTO>()
{
new WC.TipoAlertaDTO()
{
DescripcionLarga = txtDescripcion.Text
}
}
}
}
};
using (WC.FacturaClient fc = new WC.FacturaClient())
{
alertaDTOResp = fc.AlertasEjecutar(alertaDTOReq);
}
foreach (var item in alertaDTOResp.ListaDeAlertas)
{
logAlertas.Add(new Alerta()
{
AsuntoVariable = item.AsuntoVariable,
DescripcionLarga = item.TipoAlerta.FirstOrDefault().DescripcionLarga,
Destinatario = item.Destinatario,
FechaEnvio = item.FechaEnvio,
IdComercio = item.IdComercio,
});
}
PopularPager(alertaDTOResp.TotalRegistros, paginacion.Pagina);
return logAlertas;
}
catch (Exception ex)
{
MensajeFront.Mostrar(Page.Title, Resources.Facturacion.Error_Generico_Usuario, Controles_Comunes_wucMensaje.TipoMensaje.Info);
log.Error(String.Format(Resources.Facturacion.LogError, Helper.TraerNombreDelMetodo()), ex);
throw ex;
}
}
И затем я вызываю PopularPager (PopulatePager):
private void PopularPager(int conteoRegistros, int paginaActual)
{
try
{
string primero = "First";
string ultimo = "last";
string primerPagina = "1";
double cantPag = (double)((decimal)conteoRegistros / decimal.Parse(ddlTamañoPagina.SelectedValue));
int paginas = (int)Math.Ceiling(cantPag);
List<ListItem> paginasListItem = new List<ListItem>();
if (paginas > 0)
{
paginasListItem.Add(new ListItem(primero, primerPagina, paginaActual > 1));
for (int i = 1; i <= paginas; i++)
{
paginasListItem.Add(new ListItem(i.ToString(), i.ToString(), i != paginaActual));
}
paginasListItem.Add(new ListItem(ultimo, paginas.ToString(), paginaActual < paginas));
}
rptPager.DataSource = paginasListItem;
rptPager.DataBind();
}
catch (Exception ex)
{
MensajeFront.Mostrar(Page.Title, Resources.Facturacion.Error_Generico_Usuario, Controles_Comunes_wucMensaje.TipoMensaje.Info);
log.Error(String.Format(Resources.Facturacion.LogError, Helper.TraerNombreDelMetodo()), ex);
throw ex;
}
}
Я связываю данныеколичество страниц, которые я получаю от SP и количество реестров на страницу для этой repeater
, repeater
создаст каждое число на пейджере, поэтому, если у меня 1000 реестров, разделенных на 10 реестров, у меня будет 100 страниц.
То, что я пытаюсь сделать, и я думаю, что метод PopularPager
- это тот, который я должен изменить, - это ограничить количество страниц, которые человек может видеть, до 20, а когда он нажимает 20, переходит в еще 20 реестров.,То же самое происходит, если он нажимает на первый.
Как мне этого добиться?
РЕДАКТИРОВАТЬ: Перерывая различные веб-сайты, я нашел интересный способ решения этого источника:https://www.aspforums.net/Threads/106478/Numeric-paging-in-ASPNet-Repeater-with-Next-and-Previous-Button-using-C-and-VBNet/, поэтому я заменил свой первоначальный метод PopularPager
(PopulatePager) следующим образом:
private void PopularPager(int conteoRegistros, int paginaActual)
{
double dblPageCount = (double)((decimal)conteoRegistros / decimal.Parse(ddlTamañoPagina.SelectedValue));
int pageCount = (int)Math.Ceiling(dblPageCount);
List<ListItem> pages = new List<ListItem>();
int cantMaxPaginas = 20;
if (pageCount > 0)
{
pages.Add(new ListItem("Primero", "1", paginaActual > 1));
if (paginaActual != 1)
{
pages.Add(new ListItem("Atras", (paginaActual - 1).ToString()));
}
if (pageCount < cantMaxPaginas)
{
for (int i = 1; i <= pageCount; i++)
{
pages.Add(new ListItem(i.ToString(), i.ToString(), i != paginaActual));
}
}
else if (paginaActual < cantMaxPaginas)
{
for (int i = 1; i <= cantMaxPaginas; i++)
{
pages.Add(new ListItem(i.ToString(), i.ToString(), i != paginaActual));
}
pages.Add(new ListItem("...", (paginaActual).ToString(), false));
}
else if (paginaActual > pageCount - cantMaxPaginas)
{
pages.Add(new ListItem("...", (paginaActual).ToString(), false));
for (int i = paginaActual - 1; i <= pageCount; i++)
{
pages.Add(new ListItem(i.ToString(), i.ToString(), i != paginaActual));
}
}
else
{
pages.Add(new ListItem("...", (paginaActual).ToString(), false));
for (int i = paginaActual - 2; i <= paginaActual + 2; i++)
{
pages.Add(new ListItem(i.ToString(), i.ToString(), i != paginaActual));
}
pages.Add(new ListItem("...", (paginaActual).ToString(), false));
}
if (paginaActual != pageCount)
{
pages.Add(new ListItem("Siguiente", (paginaActual + 1).ToString()));
}
pages.Add(new ListItem("Ultimo", pageCount.ToString(), paginaActual < pageCount));
}
rptPager.DataSource = pages;
rptPager.DataBind();
}
Дело в том, что когда я перехожу вниз по страницам, он показывает мне n - 1 этой страницывместо, может быть, 5 из них, например: если у меня есть ... 10 11 12 13 14 15 ... если я нажму 10, это должно по крайней мере показать мне ... 5 6 7 8 9 10 ... с 10как выбран ListItem (и включен класс css), но он показывает только 3, я думаю, что проблема в этой части метода:
else if (paginaActual > pageCount - cantMaxPaginas)
{
pages.Add(new ListItem("...", (paginaActual).ToString(), false));
for (int i = paginaActual - 1; i <= pageCount; i++)
{
pages.Add(new ListItem(i.ToString(), i.ToString(), i != paginaActual));
}
}
Разница между paginaActual
и pageCount
является небольшим (Aprox 3 или 4), поэтому итерирует это небольшое количество.
Может быть, вычитание постоянного числа, может быть, еще двух может помочь?