Как я использую DataPager с Серверной Подкачкой страниц?

Я пытаюсь использовать DataPager, чтобы сделать Серверную подкачку страниц. Вот мой код



    


Код позади

protected void Page_Load(object sender, EventArgs e)
{
    ConfigureBlogPostListView();
}

private void ConfigureBlogPostListView()
{
    int pageNum;
    int.TryParse(Request.Params["page"], out pageNum);
    int pageSize = 20;

    PagedList FooBars = FooService.GetPagedFooBars(
        new PagingSettings(pageNum, pageSize));

    ListViewPagedDataSource ds = new ListViewPagedDataSource();
    ds.AllowServerPaging = true;
    ds.DataSource = FooBars;
    ds.MaximumRows = pageSize;
    ds.StartRowIndex = pageNum;
    //TotalCount is the total number of records in the entire set, not just those loaded.
    ds.TotalRowCount = FooBars.TotalCount;

    lvFooBars.DataSource = ds;
    lvFooBars.DataBind();

    pgrFooBars.PageSize = pageSize;
    pgrFooBars.SetPageProperties(pageNum, FooBars.TotalCount, true);
}

PagedList происходит из полезного сообщения RobConery http://blog.wekeroad.com/2007/12/10/aspnet-mvc-pagedlistt/.

Проблема состоит в том, что DataPager, кажется, использует свойство Count ListView для определения общего количества записей, которое в этом случае равняется 20. Так или иначе это должно знать, что существует 1,500, не 20 общих записей. DataPager имеет свойство TotalRowCount, но это только для чтения.

Я никогда не видел примера DataPager с Серверной подкачкой страниц, но предполагал, что она могла сделать Серверную Подкачку страниц, иначе что хороший атрибут QueryStringField?

Я знаю, что можно сделать, пользовательское решение для подкачки страниц с помощью методологии как 4GuysFromRolla сделало здесь http://www.4guysfromrolla.com/articles/031506-1.aspx, но я сначала хотел бы знать, возможно ли решение с DataPager прежде, чем создать настраиваемое решение.

ОБНОВИТЕ больше я смотрю на это, больше что я прихожу к выводу, что это не возможно и что к сожалению, datapager является управлением, предназначенным для небольших веб-сайтов только. То, что я хочу сделать, должно действительно быть довольно простым, если бы управление было создано правильно. Я хочу смочь сказать

dpFooBars.TotalRowCountComputed = false;
dpFooBars.TotalRowCount = AnyNumberThatISoChoose;

Я искал некоторый взлом для выполнения того же самого, но кажется, что TotalRowCount datapager вычисляется из фактического количества объектов в источнике данных, с которым это связывается. Это кажется очень нечетным мне, что Microsoft создала бы ListViewPagedDataSource () класс и DataPager одновременно и не имела бы их работа правильно вместе, но это, кажется, было тем, что произошло.

ОБНОВИТЕ 2 (АГА МОМЕНТ?) Кажется, что было возможно сделать серверную подкачку страниц начиная с.Net 2.0 при помощи ObjectDataSource и настройки SelectCountMethod (). Я полагаю, что должно быть возможно настроить ObjectDataSource для удовлетворения моим потребностям. Хм. Я ухожу в течение выходных, таким образом, это будут несколько дней для меня, чтобы видеть, работает ли это. Останьтесь настроенными, правоверные.

13
задан John 16 July 2010 в 15:59
поделиться

2 ответа

Кажется, единственный способ заставить серверную подкачку работать с DataPager - использовать LinqDataSource в вашей разметке ( обновление: это неверно, см. ниже ), и установите DataSourceID вашего ListView (как в примере ScottGu - шаг 6 ), а не через свойство ListView DataSource. Однако я обнаружил, что есть трюк , чтобы сделать это более работоспособным, чтобы вы могли определять свой запрос LinqDataSource через код программной части, а не в разметке (обратите внимание, в статье говорится, что это будет работать с любым элементом управления DataSource, но Не думаю, что это так).

Это, вероятно, не поможет в вашей ситуации, поскольку я заметил, что вы вызываете какую-то службу, которая, вероятно, не будет (и не должна) возвращать результат IQueryable, необходимый для работы. Вот оно, на всякий случай ...

aspx разметка:

<asp:ListView ID="lvFooBars" DataSourceID="dsLinq" ....>
   ......
</asp:ListView>

<asp:DataPager ID="pgrFooBars" PagedControlID="lvFooBars" 
    QueryStringField="page" runat="server" >
<Fields>
    <asp:NumericPagerField />
</Fields>
</asp:DataPager>

<asp:LinqDataSource id="dsLinq" runat="server" OnSelecting="dsLinq_Selecting" />

код программной части:

protected void dsLinq_Selecting(object sender, LinqDataSourceSelectEventArgs e)
{
    //notice this method on FooService requires no paging variables
    e.Result = FooService.GetIQueryableFooBars(); 
}

Примечание. MSDN указывает в отношении атрибута QueryStringField :

Установка этого свойства полезна, если вы хочу иметь все страницы данных проиндексировано поисковой системой. Этот происходит, потому что элемент управления производит разные URL для каждой страницы данных.

Обновление: на самом деле вы можете заставить это работать, используя элемент управления ObjectDataSource вместо элемента управления LinqDataSource - см. эту статью и загрузите образец . Хотя использование ObjectDataSource не так просто, как использование элемента управления LinqDataSource, он использует меньше волшебных вещей linq (вместо этого он использует кучи волшебных строк, которые сопоставляются с методами уровня бизнеса / данных) и позволяет использовать IEnumerable для вашего метода доступа к данным вместо IQueryable.

Тем не менее, я никогда не был фанатом встраивания какого-либо элемента управления DataSource в свою разметку пользовательского интерфейса (я считаю, что это необходимо), поэтому я бы, вероятно, держался подальше от элемента управления DataPager, за исключением небольших приложений, как вы предложили в своем первое обновление.

Джон, я заметил еще одну вещь: вы пытаетесь объединить стандартные серверные элементы управления Asp.Net (которые полагаются на ViewState) с классом PagedList, который был разработан как вспомогательный класс для приложений Asp.Net Mvc. Хотя это потенциально может сработать, могут быть более простые маршруты.

3
ответ дан 2 December 2019 в 00:45
поделиться

Джон, я сделал небольшое доказательство концепции здесь, чтобы вы могли увидеть код. Я сделал это как можно проще, чтобы не было пуха. Пожалуйста, дайте мне знать, если есть какой-то атрибут, который вам нужен, и я пересмотрю его.

Вещи, которые выделились:

  1. Данные должны быть привязаны в событии OnPreRender пейджера, когда вы не используете объект DataSource (xml, Sql, Access...). Я почти уверен, что это ваша проблема, потому что именно здесь у меня было больше всего проблем.

  2. Viewstate должен быть включен для ListView и пейджера (по умолчанию он включен)

Code-Behind:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class _Default : System.Web.UI.Page 
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            this.BindListData();
        }
    }

    protected void dp_PreRender(object sender, EventArgs e)
    {
        this.BindListData();
    }

    protected void BindListData()
    {
        List<Nums> n = new List<Nums>();
        for (int i = 0; i <= 100; i++)
        {
            n.Add(new Nums { Num1 = i, Num2 = i * 3 });
        }

        this.lvMyGrid.DataSource = n;
        this.lvMyGrid.DataBind();
    }
}

public class Nums
{
    public int Num1 { get; set; }
    public int Num2 { get; set; }
}

ASPX (оставив все остальное):

<asp:DataPager OnPreRender="dp_PreRender" runat="server" ID="dpMyPager" QueryStringField="page" PagedControlID="lvMyGrid" PageSize="15">
    <Fields>
        <asp:NumericPagerField />
    </Fields>
</asp:DataPager>

<asp:ListView runat="server" ID="lvMyGrid" DataKeyNames="Num1">
    <LayoutTemplate>
        <asp:Literal runat="server" ID="itemPlaceholder" />
    </LayoutTemplate>
    <ItemTemplate>
        <div style="border: 1px solid red; padding: 3px; margin: 5px; float: left; clear: both;">
        <%# Eval("Num1") %> : <%# Eval("Num2") %>
        </div>
    </ItemTemplate>
</asp:ListView>

Наслаждайтесь, дайте мне знать, если есть что-то еще в этом, что вам нужно.

mike

0
ответ дан 2 December 2019 в 00:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: