Элемент управления ListView

189

ListView — это исключительно гибкий привязанный к данным элемент управления, отображающий свое содержимое на основе определяемых вами шаблонов. В отличие от Repeater, элемент ListView добавляет высокоуровневые средства, такие как возможность выбора и редактирования, которые работают точно так же, как аналогичные средства GridView. Но в отличие от GridView, элемент ListView не поддерживает модели, основанной на полях, для создания быстрых и простых таблиц с минимальным кодом разметки.

С разных точек зрения ListView можно трактовать либо как более гибкую версию GridView, требующую больше работы, либо как более насыщенную средствами версию простого элемента Repeater, который появился в ASP.NET 1.x.

ListView включает более широкий набор шаблонов, чем GridView. Эти шаблоны перечислены в таблице ниже:

Шаблоны ListView
Режим Описание
ItemTemplate

Устанавливает содержимое каждого элемента данных (если вы не используете AlternatingItemTemplate) или каждой нечетной ячейки (если используете)

AlternatingItemTemplate

Применяется в сочетании с ItemTemplate для различного форматирования четных и нечетных строк

ItemSeparatorTemplate

Устанавливает содержимое разделителя, размещаемого между элементами

SelectedItemTemplate

Устанавливает содержимое элемента, выбранного в данный момент. Можно использовать то же содержимое, что и ItemSeparatorTemplate, но с другим форматированием, или же выбрать отображение расширенного вида с дополнительными деталями для выбранного элемента

EditItemTemplate

Устанавливает элементы управления, используемые для элемента в режиме редактирования

InsertItemTemplate

Устанавливает элементы управления, используемые для вставки нового элемента

LayoutTemplate

Устанавливает разметку, обертывающую ваш список элементов

GroupTemplate

Устанавливает разметку, обертывающую каждую группу элементов, если используется средство группирования

GroupSeparatorTemplate

Устанавливает содержимое разделителя групп элементов

EmptyItemTemplate

Устанавливает содержимое, используемое для заполнения пустых значений в последней группе, если применяется группирование. Например, если создаются группы из 5 элементов, а источником данных является коллекция из 13 объектов, то в последней группе будет не хватать 2 элементов

EmptyDataTemplate

Устанавливает разметку, используемую в случае пустого привязанного объекта данных (т.е. не содержащего записей или объектов)

Наиболее частая причина использования ListView связана с необходимостью создания необычной компоновки, например, чтобы построить таблицу, размещающую более одного элемента в одной строке, или же вообще не использующую обычную табличную компоновку. При построении страницы, предназначенной для отображения больших объемов данных, разработчики на ASP.NET обычно сначала обращаются к GridView, a ListView применяют в более специализированных сценариях.

При отображении некоторых данных в ListView вы следуете тому же процессу, что и в случае элемента GridView, состоящего из столбцов TemplateField. Сначала вы создаете разметку для шаблонов, которые хотите использовать. Как минимум, понадобится шаблон ItemTemplate, который представляет содержимое для каждого элемента. Ниже приведен пример:

<asp:ListView ID="listEmployees" runat="server" DataSourceID="getEmployeesSDS">
	<ItemTemplate>
	    <span>
	    <b>
	        <%# Eval("EmployeeID") %> - 
		    <%# Eval("TitleOfCourtesy") %> <%# Eval("FirstName") %>
	        <%# Eval("LastName") %>
	    </b>
	    <hr />
	    <small><i>
	        <%# Eval("Address") %><br />
	        <%# Eval("City") %>, <%# Eval("Country") %>,
		    <%# Eval("PostalCode") %><br />
	        <%# Eval("HomePhone") %></i>
	        <br />
	        <br />
	        <%# Eval("Notes") %>
	    </small><hr /><br />
	    </span>
	</ItemTemplate>
</asp:ListView>

<asp:SqlDataSource ID="getEmployeesSDS" runat="server"
            ConnectionString="<%$ ConnectionStrings:Northwind %>"
            SelectCommand="SELECT * FROM Employees" />

При визуализации элемент управления ListView осуществляет проход по привязанным данным и отображает ItemTemplate для каждого элемента. Все это содержимое размещается внутри обычного элемента <span>:

Использование ListView

Часто возникает желание определить шаблон LayoutTemplate для получения большего контроля над расположением элементов. В этом случае список элементов размещается внутри LayoutTemplate. Поведение по умолчанию элемента ListView без LayoutTemplate эквивалентно использованию примерно следующего шаблона LayoutTemplate:

<asp:ListView ID="listEmployees" runat="server" DataSourceID="getEmployeesSDS">
	<ItemTemplate>
	    ...
	</ItemTemplate>
	<LayoutTemplate>
	    <asp:PlaceHolder ID="itemPlaceHolder" runat="server"></asp:PlaceHolder>
	</LayoutTemplate>
</asp:ListView>

При создании LayoutTemplate для ListView потребуется указать, куда должно быть вставлено содержимое ItemTemplate. Это делается добавлением заполнителя - элемент, который будет дублироваться по одному для каждого элемента привязанных данных. Чтобы обозначить элемент как заполнитель, необходимо просто установить его ID в itemPlaceHolder, как показано выше в примере.

Заполнитель должен быть серверным элементом управления — другими словами, ему нужен атрибут runat="server". В этом примере используется удобный веб-элемент управления PlaceHolder, но вместо него можно указать серверный элемент <span> или <div>.

Именно шаблон LayoutTemplate придает такую гибкость элементу ListView. Другие элементы управления данными используют шаблоны для содержимого, но не для всей структуры. С помощью LayoutTemplate можете легко адаптировать этот пример для использования таблицы. Например, если вы хотите поместить каждый элемент в отдельную строку (как это делает GridView), для заполнителя элемента необходимо использовать строку таблицы (элемент <tr>):

<LayoutTemplate>
	<table border="1">
		<tr id="itemPlaceHolder" runat="server" />
</LayoutTemplate>

Теперь каждый элемент может начинать новую строку (с помощью <tr>) и добавлять ячейки по мере необходимости (посредством <td>):

<ItemTemplate>
	<tr>
		<td>...</td>
		...
	</tr>
</ItemTemplate>

По сравнению с GridView, элемент Listview обладает одним концептуальным недостатком — у него есть только один шаблон для отображения элементов. Чтобы понять, чем это может ограничивать, рассмотрим, что случится, если вы захотите создать многостолбцовое отображение с использованием Listview. Вам нужно будет добавить заголовки столбцов над Listview, а затем определить содержимое всех столбцов в ItemTemplate. Это отлично работает, но приводит к серьезным неудобствам, когда требуется внести кажущиеся тривиальными изменения — вроде изменения последовательности столбцов.

Ради интереса можете создать табличную компоновку, которая была бы невозможной для обычного элемента GridView — такую, которая размещает каждый элемент в отдельном столбце. Концептуально это не сложно. Нужно просто использовать ячейку таблицы (элемент <td>) в качестве заполнителя:

<LayoutTemplate>
	<table border="1">
	    <tr id="groupPlaceholder" runat="server" 
	        style="vertical-align:top; border:1px solid black">
	        <td id="itemPlaceHolder" runat="server" />
	    </tr>
	</table>
</LayoutTemplate>

Теперь шаблон LayoutTemplate должен начинаться с дескриптора <td>:

<ItemTemplate>
	<td>
	    <b>
	        <%# Eval("EmployeeID") %>- 
	<%# Eval("TitleOfCourtesy") %> <%# Eval("FirstName") %> <%# Eval("LastName") %></b><hr />
	    <small><i>
	        <%# Eval("Address") %><br />
	        <%# Eval("City") %>, <%# Eval("Country") %>,
	<%# Eval("PostalCode") %><br />
	        <%# Eval("HomePhone") %></i><br />
	        <br />
	        <%# Eval("Notes") %><br />
	        <br />
	    </small>
	</td>
</ItemTemplate>

Результат быстро станет трудночитаемым, если отображаемый набор данных окажется достаточно объемным (если не применять разбиение на страницы):

Необычная компоновка с ListView

Группирование

Элемент Listview предоставляет возможность создать несколько более структурированные отображения, которые решают проблему, показанную на рисунке выше. Трюк заключается в применении группирования, которое позволяет указать дополнительный уровень компоновки, используемой для размещения небольших групп записей внутри общей компоновки.

Чтобы воспользоваться группированием, начать следует с установки свойства GroupItemCount, определяющего количество элементов данных в каждой группе:

<asp:ListView ID="listEmployees" GroupItemCount="3" ...>

К сожалению, средство группирования ListView не работает в связке с информацией из привязанных данных. Например, в случае привязки коллекции объектов Product не существует способа разделить их по группам на основе ценовых диапазонов или категорий товаров. Вместо этого группы ListView всегда имеют фиксированный размер. Максимум, что можно — это сделать размер групп настраиваемым пользователем (скажем, применив дополнительный элемент управления, подобный раскрывающемуся списку, из которого пользователь сможет выбирать число для применения в GroupItemCount).

После установки размера группы понадобится изменить LayoutTemplate. Это связано с тем, что общая компоновка более не содержит элементов данных. Вместо этого она содержит группы, которые, в свою очередь, содержат элементы. Чтобы отразить этот факт, вы должны изменить ID с itemPlaceholder на groupPlaceholder. В данном примере каждая группа представляет собой отдельную строку:

<LayoutTemplate>
    <table border="1">
        <tr id="groupPlaceholder" runat="server"></tr>
    </table>
</LayoutTemplate>

Далее необходимо применить шаблон GroupTemplate, который используется в качестве оболочки для каждой группы. GroupTemplate должен предоставлять заполнитель элемента, который находился ранее в LayoutTemplate. В этом примере каждый элемент является отдельной ячейкой:

<GroupTemplate>
	<tr>
	    <td runat="server" id="itemPlaceholder" />
	</tr>
</GroupTemplate>

Теперь ItemTemplate может начинаться с дескриптора <td>, так что каждый элемент — это ячейка внутри строки. В свою очередь, каждая строка — это группа из трех элементов данных в общей таблице. На рисунке ниже показан результат:

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

Разбиение на страницы

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

Идея, положенная в основу DataPager, заключается в том, что он предлагает простой, согласованный способ использования разбиения на страницы для широкого разнообразия элементов управления. В настоящее время ListView — единственный элемент, поддерживающий DataPager. Однако вполне резонно ожидать, что в будущих версиях DataPager будет работать с другими элементами управления ASP.NET.

Одно из преимуществ DataPager заключается в том, что вам предоставляется гибкость в произвольном размещении его внутри общей компоновки — просто за счет размещения дескриптора в правильном месте LayoutTemplate. Рассмотрим пример совершенно типичного размещения DataPager в нижней части ListView, с кнопками для перемещения вперед и назад на одну страницу либо для быстрого перехода на первую или последнюю страницы:

<LayoutTemplate>
	<table border="1">
	    <tr id="groupPlaceholder" runat="server"></tr>
	</table>
	<asp:DataPager runat="server" ID="ContactsDataPager" PageSize="3">
	    <Fields>
	        <asp:NextPreviousPagerField ShowFirstPageButton="true" ShowLastPageButton="true"
	            FirstPageText="|&lt;&lt; " LastPageText=" &gt;&gt;|"
	            NextPageText=" &gt; " PreviousPageText=" &lt; " />
	    </Fields>
	</asp:DataPager>
</LayoutTemplate>

DataPager также усекает привязанные данные, так что ListView получает соответствующее подмножество этих данных. В текущем примере страницы ограничены тремя элементами. На рисунке показаны кнопки перемещения по страницам:

Работа ListView в сочетании с DataPager
Пройди тесты
Лучший чат для C# программистов