Если вы уже использовали элементы управления 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(); }
Теперь, если вы проверите функциональность, она должна работать правильно.
Надеюсь, это было полезно.
С уважением,
Хаджан