Ограничьте количество страниц при разбивке по страницам, используя повторитель в веб-формах. - PullRequest
0 голосов
/ 15 апреля 2019

Я нахожусь в проекте 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), поэтому итерирует это небольшое количество.

Может быть, вычитание постоянного числа, может быть, еще двух может помочь?

...