И GridView
, и ListView
могут выполнять пейджинг, если вы добавите в них DataPager
. ListView
является шаблонным элементом управления - дисплей полностью настроен, поэтому вам нужно свернуть свои собственные «столбцы»; мне не очень пригодится GridView
, поэтому я не знаю об этом.
Что касается поиска и сортировки, то для него есть какая-то встроенная поддержка, которая становится бесполезной, если вам нужен источник данных, ASP.NET не может запрашивать напрямую - ObjectDataSource
позволяет вам создать свой собственный код доступа к данным, но вы также необходимо реализовать все, что не может быть сделано автоматически.
Для поиска вы можете обработать событие ODS Selecting
, вы можете передать произвольные параметры методу запроса; Я считаю, что есть также какой-то способ автоматически получить управляющие значения / параметры строки запроса и т. Д.
Для сортировки ListView
позволяет добавить Button
s, где CommandName="Sort"
и CommandArgument="[column to sort by]"
. Я полагаю, что при использовании нестандартного источника данных они просто будут работать. При использовании ObjectDataSource
все, что они делают, это заставляют ListView
отслеживать «выражение сортировки», которое вы можете передать в источник данных в событии ODS.Selecting
. Формат выражения сортировки указан ... где-то, что я никогда не смогу найти, когда мне это нужно. При использовании сортировки по одному столбцу это будет либо "[column name]"
для сортировки по возрастанию, либо "[column name] DESC"
для сортировки по убыванию. Вы можете передать это непосредственно ObjectQuery.OrderBy
; EntityFramework.Extended
также предоставляет этот метод расширения для новой поверхности API. ListView
(я полагаю) обрабатывает только сортировку по одному столбцу, для сортировки по нескольким столбцам вы все равно должны сами управлять выражением сортировки.
Документация на все это разбросана, хорошая отправная точка - , это руководство , его продолжение и ссылки для ListView
, которые вы можете найти на боковой панели слева.
Мой проект также имеет достаточно простое использование ListView
в сочетании с ObjectDataSource
- это означает, что ни одна из его частей не использует магические функции RAD, что следует ниже. Я извлек его из моего реального проекта, поэтому в нем могут быть незначительные несоответствия.
ListView
+ ObjectDataSource
Пример
В следующем примере извлекаются «сообщения» (например, объявления о новостях на портале компании) из службы WCF (не включены).
MessagesDataSource.cs
Делегат ObjectDataSource
, который вызывает службу WCF. Источник данных отвечает за:
- фильтрация на основе параметров
username
и type
- сортировка на основе выражения сортировки в параметре
sort
- paging как указано в параметрах
skip
и take
- названы так, чтобы соответствовать операторам LINQ
Поскольку мы используем ObjectDataSource
, все это было реализовано в делегате - вот где в конечном счете вызывается служба.
public enum MessageType
{
None = 0,
All,
General,
OfficeHoursUpdate,
// …
}
[DataObject]
public class MessagesDataSource : IDisposable
{
IMessagesService _svc = new MessagesServiceClient();
[DataObjectMethod(DataObjectMethodType.Select)]
public IEnumerable<Message> Select(string username, MessageType type, string sort, int skip, int take)
{
return _svc.GetMessages(username, type, sort, skip, take);
}
public int SelectCount(string username, MessageType type, string sort, int skip, int take)
{
return _svc.CountMessages(username, type);
}
}
Messages.ascx
Отображает список сообщений в виде таблицы с одним <tbody>
на сообщение, с одной строкой, разделенной на столбцы для «заголовков» сообщения, и второй строкой, в которой все столбцы объединены для тела сообщения. Примечания к сведению:
- Если в раскрывающемся списке выбрано значение,
ListView
обновляется, начиная с первой страницы.
- Все параметры, которые принимают методы
MessageDataSource.Select()
и .SelectCount()
, должны быть объявлены в ODS <SelectParameters>
. (Visual Studio выдаст ошибку, если они не совпадают.)
- Атрибут
TypeName
элемента управления ObjectDataSource указывает делегат ODS, экземпляр которого создается ODS. Для большего контроля над этим обработайте события ObjectCreating
/ ObjectCreated
ODS. (Например, вы можете передать содержащий элемент управления делегату ODS.)
- Значения параметров, названных атрибутами
StartRowIndexParameterName
и MaximumRowsParameterName
, будут автоматически предоставляться пейджером данных.
- Я не верю, что значение параметра
SortParameterName
заполняется ListView
при использовании ObjectDataSource
- оно может или не может быть при использовании GridView
. Я также не думаю, что в этом случае это необходимо, но опять же, никому не мешает держать его там.
- Я опустил поля пейджера данных, они здесь просто загромождены.
- Значения
CommandArgument
сортировки LinkButton
в заголовке не должны совпадать со свойствами объектов данных и могутна самом деле быть совершенно произвольным.
<asp:Label ID="lblType" runat="server" AssociatedControlID="ddlType" Text="Message Type:"/>
<asp:DropDownList runat="server" ID="ddlType" AutoPostBack="true"
OnSelectedIndexChanged="ddlType_SelectedIndexChanged"
OnLoad="ddlType_Load" />
<table>
<asp:ListView ID="lvMessages" runat="server" DataSourceID="dsMessages" ItemPlaceholderID="message">
<LayoutTemplate>
<thead>
<tr>
<th>
<asp:LinkButton runat="server" Text='Timestamp'
CommandName="Sort" CommandArgument="Timestamp" />
<asp:Literal ID="lvMessages__Timestamp" runat="server"
OnPreRender="UpdateSortIndicator" />
</th>
<th>
Sender
</th>
<th>
<asp:LinkButton runat="server" Text='Subject'
CommandName="Sort" CommandArgument="Subject" />
<asp:Literal ID="lvMessages__Subject" runat="server"
OnPreRender="UpdateSortIndicator" />
</th>
</tr>
</thead>
<tfoot>
<tr>
<td colspan="3">
<asp:DataPager ID="dpMessages" runat="server"
PageSize="10" PagedControlID="lvMessages"
OnInit="dpMessages_Init">
<Fields>
<%-- Data Pager Fields --%>
</Fields>
</asp:DataPager>
</td>
</tr>
</tfoot>
<%--
The following tag gets replaced with the rendered contents of
ItemTemplate for each data item
--%>
<tbody runat="server" id="message" />
</LayoutTemplate>
<ItemTemplate>
<tbody>
<tr>
<td>
<%# Eval("Timestamp") %>
</td>
<td>
<%# Eval("Sender") %>
</td>
<td>
<%# Eval("Subject") %>
</td>
</tr>
<tr>
<td colspan="3">
<%# Eval("Body") %>
</td>
</tr>
</tbody>
</ItemTemplate>
<EmptyDataTemplate>
No messages loaded!
</EmptyDataTemplate>
</asp:ListView>
</table>
<asp:ObjectDataSource ID="dsMessages" runat="server" TypeName="Foo.MessagesDataSource"
DataObjectTypeName="Foo.Message" SelectMethod="Select"
SelectCountMethod="SelectCount" StartRowIndexParameterName="skip" MaximumRowsParameterName="take"
OnSelecting="dsMessages_Selecting" EnablePaging="true" SortParameterName="sort">
<SelectParameters>
<asp:Parameter Name="username" />
<asp:Parameter Name="scope" />
<asp:Parameter Name="sort" />
<asp:Parameter Name="skip" />
<asp:Parameter Name="take" />
</SelectParameters>
</asp:ObjectDataSource>
Messages.ascx.cs
Этот класс достаточно прост и имеет дело главным образом с инициализацией страницы и такими проблемами, как индикаторы сортировки.К большинству «интересных» фрагментов добавлены комментарии.
public partial class Messages : UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// Initialise the dropdown list values
var types = Enum.GetValues(typeof(MessageType));
types.Remove(MessageType.None);
foreach (var t in types)
{
ddlType.Items.Add(new ListItem(t.ToString()));
}
// Default message filter and sort
Type = MessageType.All;
lvMessages.Sort("Timestamp", SortDirection.Descending);
}
}
private MessageType _type;
public MessageType Type
{
get { return _type; }
set
{
if (!_type.Equals(value))
{
ddlType.SelectedValue = value.ToString();
_type = value;
}
}
}
private static readonly IDictionary<SortDirection, string> SortIndicators =
new Dictionary<SortDirection, string>
{
{SortDirection.Ascending, "\u25b4"}, // upwards triangle
{SortDirection.Descending, "\u25be"} // downwards triangle
};
/// This is where you can programmatically add / change the values of
/// parameters that will get passed to MessagesDataSource.Select()
protected void dsMessages_Selecting(object sender, ObjectDataSourceSelectingEventArgs e)
{
// Add "filter" parameters that have to be determined programmatically.
e.InputParameters["username"] = GetUsernameLoggedIn();
e.InputParameters["type"] = Type;
}
/// When the message type changes, go back to the first page
protected void ddlType_SelectedIndexChanged(object sender, EventArgs e)
{
Type = (MessageType) ddlType.SelectedValue);
var pager = (DataPager)lvMessages.FindControl("dpMessages");
if (pager == null)
{
((IPageableItemContainer)lvMessages).SetPageProperties(0, 10, true);
}
else
{
pager.SetPageProperties(0, pager.PageSize, true);
}
}
/// Reload the value from the dropdown list.
protected void ddlType_Load(object sender, EventArgs e)
{
Type = (MessageType) ddlType.SelectedValue;
}
protected void UpdateSortIndicator(object sender, EventArgs e)
{
var indicator = (Literal) sender;
if (indicator.ID.EndsWith("__"+ lvMessages.SortExpression))
{
indicator.Text = SortIndicators[lvMessages.SortDirection];
}
else
{
indicator.Text = "";
}
}
}
Отказ от ответственности: Я не претендую на звание авторитета в этой теме, и на самом деле я довольно новичок в.СЕТЬ.Это как раз то, с чем мне пришлось столкнуться в последнее время, и меня также смутила разбросанная документация, которая, как правило, либо использовала ярлыки для решения части проблемы (т. Е. Либо использовала GridView для автоматического получения полного представления, либо использовала ADO.NETисточник данных вместо пользовательского кода доступа к данным);или потратить слишком много места на пух (например, снимки экрана с кнопкой, которую нужно нажать в мастере Visual Studio.)