Статьи

Пейджинг ASP.NET ListView с использованием DataPager без использования DataSource Control

Если вы уже использовали элементы управления ASP.NET ListView и DataPager, вы знаете, как легко вы можете отображать свои данные с помощью пользовательских шаблонов и обеспечивать функциональность разбиения на страницы. Вы можете сделать это всего за несколько минут. Элементы управления ListView и DataPager прекрасно работают в сочетании с элементами управления DataSource (SqlDataSource, LinqDataSource, ObjectDataSource и т. Д.), Однако, если вы используете их с настраиваемым сбором данных, без использования элементов управления Data Source, вы можете обнаружить непредвиденное поведение и добавить некоторые немного больше кода, чтобы заставить его работать.

Примечание: я видел вопрос, связанный с этой проблемой, задаваемый несколько раз на разных форумах asp.net, поэтому я подумал, что было бы неплохо документировать его здесь.

Давайте вместе создадим рабочую демонстрацию …

1. Создайте пример проекта веб-приложения ASP.NET, добавьте новую страницу ASPX.

2. Добавьте элемент управления ListView и измените разметку, чтобы в итоге получилось следующее:

<asp:ListView ID="ListView1" runat="server">
        <LayoutTemplate>
            <ul>
                <asp:PlaceHolder ID="itemPlaceholder" runat="server" />
            </ul>
        </LayoutTemplate>
        <ItemTemplate>
            <li>
                <%# Eval("Name") %> (<%# Eval("Currency") %> <%# Eval("Price") %>)
            </li>
        </ItemTemplate>
        <EmptyDataTemplate>
            No data
        </EmptyDataTemplate>
        </asp:ListView>

Элемент управления ListView имеет три определенных шаблона:

  • LayoutTemplate — где мы определяем способ представления наших данных. У нас есть PlaceHolder, куда будут помещены данные из ItemTemplate. ListView распознает это автоматически.
  • ItemTemplate — где элемент управления ListView будет отображать элементы из источника данных. Он автоматически выполняет итерацию по каждому элементу в коллекции (как и любой другой элемент управления источником данных)
  • EmptyDataTemplate — если в коллекции нет данных, этот шаблон будет отображаться.

3. Добавьте элемент управления DataPager и измените разметку следующим образом:

        <asp:DataPager ID="lvDataPager1" runat="server" PagedControlID="ListView1" PageSize="5">
            <Fields>
                <asp:NumericPagerField ButtonType="Link" />
            </Fields>
        </asp:DataPager>

Мы добавляем элемент управления DataPager, связываем его с элементом управления ListView1 и добавляем свойство PageSize. После этого нам нужно определить <Fields>, куда мы помещаем тип поля и тип кнопки.

Если бы мы связывались из Data Source Control (SqlDataSource, LinqDataSource или любого другого …), это было бы так, и ListView и DataPager работали бы отлично. Однако если мы свяжем пользовательский сбор данных с ListView без использования элементов управления Data Source, у нас будут проблемы с разбиением на страницы.

Давайте добавим пользовательские данные в наш код C # и свяжем их с ListView.

4. C # код, добавляющий пользовательский сбор данных

— Определить класс продукта

public class Product
{
    public string Name { get; set; }
    public decimal Price { get; set; }
    public string Currency { get; set; }
}

— Определить метод, который будет создавать список продуктов (пример данных)

List<Product> SampleData()
{
    List<Product> p = new List<Product>();
    p.Add(new Product() { Name = "Microsoft Windows 7", Price = 70, Currency = "USD" });
    p.Add(new Product() { Name = "HP ProBook", Price = 320, Currency = "USD" });
    p.Add(new Product() { Name = "Microsoft Office Home", Price = 60, Currency = "USD" });
    p.Add(new Product() { Name = "NOKIA N900", Price = 350, Currency = "USD" });
    p.Add(new Product() { Name = "BlackBerry Storm", Price = 100, Currency = "USD" });
    p.Add(new Product() { Name = "Apple iPhone", Price = 400, Currency = "USD" });
    p.Add(new Product() { Name = "HTC myTouch", Price = 200, Currency = "USD" });            
    return p;
}

Этот метод должен быть частью класса страницы ASPX (например, внутри класса страницы _Default, если ваша страница — Default.aspx)

— Привязать пример данных к ListView на Page_Load

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        BindListView();
    }
}

void BindListView()
{
    ListView1.DataSource = SampleData();
    ListView1.DataBind();
}

Теперь запустите проект, и вы увидите отображаемые данные, в которых будут показаны только первые пять элементов. Пейджер данных должен иметь две страницы (1 2), и вы сможете щелкнуть по второй странице, чтобы перейти к последним двум элементам в коллекции.

Теперь, если вы нажмете на страницу 2 , вы увидите, что она не будет отображать последние два элемента автоматически, вместо этого вам придется снова щелкнуть на странице 2, чтобы увидеть последние два элемента. После, если вы нажмете на страницу 1 , вы столкнетесь с другой проблемой, где отображаются пять элементов, но отображаются данные для двух последних элементов в ListView (см. Печать экрана ниже)

 

Если вы заметили на предыдущих двух рисунках, поведение, кажется, не работает должным образом. Проблема в том, что DataPager не знает о текущем свойстве изменения страницы ListView. Поэтому мы должны явно установить свойства страницы DataPager в событии PagePropertiesChanging в ListView. Вот что нам нужно сделать:

1. Добавьте событие OnPagePropertiesChanging в элемент управления ListView.

<asp:ListView ID="ListView1" runat="server" OnPagePropertiesChanging="ListView1_PagePropertiesChanging">

2. Реализуйте метод ListView1_PagePropertiesChanging

protected void ListView1_PagePropertiesChanging(object sender, PagePropertiesChangingEventArgs e)
{
    //set current page startindex, max rows and rebind to false
    lvDataPager1.SetPageProperties(e.StartRowIndex, e.MaximumRows, false);

    //rebind List View
    BindListView();
}

Теперь, если вы проверите функциональность, она должна работать правильно.

Надеюсь, это было полезно.

С уважением,
Хаджан