Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этом руководстве мы рассмотрим примеры форматирования внешнего вида элементов управления DataList и Repeater с помощью функций форматирования в шаблонах или обработки события DataBound.
Введение
Как мы видели в предыдущем руководстве, DataList предлагает ряд свойств, связанных со стилем, которые влияют на его внешний вид. В частности, мы узнали, как назначать классы CSS по умолчанию свойствам DataList HeaderStyle
, ItemStyle
, AlternatingItemStyle
и SelectedItemStyle
. Помимо этих четырех свойств, DataList включает ряд других свойств, связанных со стилем, таких как Font
, ForeColor
, BackColor
и BorderWidth
. Элемент управления Repeater не содержит свойств, связанных со стилем. Любые такие параметры стиля должны быть сделаны непосредственно в разметке в шаблонах Repeater.
Однако зачастую способ форматирования данных зависит от самих данных. Например, при перечислении продуктов может потребоваться отобразить сведения о продукте светло-серым цветом шрифта, если он недоступен, или UnitsInStock
выделить значение, если оно равно нулю. Как мы видели в предыдущих руководствах, GridView, DetailsView и FormView предлагают два различных способа форматирования внешнего вида на основе данных:
- Событие
DataBound
создает обработчик событий для соответствующегоDataBound
события, которое срабатывает после привязки данных к каждому элементу (для GridView это былоRowDataBound
событие; для DataList и Repeater этоItemDataBound
событие). В этом обработчике событий можно проверить только привязанные данные и принять решения о форматировании. Мы рассмотрели этот метод в учебнике Пользовательское форматирование на основе данных . - Функции форматирования в шаблонах при использовании TemplateFields в элементах управления DetailsView или GridView или шаблона в элементе управления FormView можно добавить функцию форматирования в класс кода программной части ASP.NET страницы, уровень бизнес-логики или любую другую библиотеку классов, доступную из веб-приложения. Эта функция форматирования может принимать произвольное количество входных параметров, но должна возвращать HTML-код для отрисовки в шаблоне. Функции форматирования были впервые рассмотрены в руководстве Использование TemplateFields в элементе управления GridView .
Оба этих метода форматирования доступны в элементах управления DataList и Repeater. В этом руководстве мы рассмотрим примеры использования обоих методов для обоих элементов управления.
Использование обработчикаItemDataBound
событий
Когда данные привязаны к DataList либо из элемента управления источником данных, либо путем программного назначения данных свойству элемента управления DataSource
и вызова его DataBind()
метода, возникает событие DataList DataBinding
, источник данных перечисляется, и каждая запись данных привязана к DataList. Для каждой записи в источнике данных DataList создает DataListItem
объект, который затем привязывается к текущей записи. Во время этого процесса DataList вызывает два события:
ItemCreated
срабатывает послеDataListItem
созданияItemDataBound
срабатывает после привязки текущей записи кDataListItem
Ниже описан процесс привязки данных для элемента управления DataList.
Срабатывает событие DataList
DataBinding
Данные привязаны к DataList
Для каждой записи в источнике данных
- Создание
DataListItem
объекта - Сожмите
ItemCreated
событие - Привяжите запись к
DataListItem
- Сожмите
ItemDataBound
событие - Добавление в
DataListItem
коллекциюItems
- Создание
При привязке данных к элементу управления Repeater выполняется та же последовательность шагов. Единственное отличие заключается в том, что вместо создаваемых DataListItem
экземпляров repeater использует RepeaterItem
s.
Примечание
Проницательный читатель, возможно, заметил небольшую аномалию между последовательностью шагов, которые выполняются, когда DataList и Repeater привязаны к данным, по сравнению с привязкой GridView к данным. В конце процесса привязки данных GridView вызывает DataBound
событие, однако ни элемент управления DataList, ни Repeater не имеют такого события. Это связано с тем, что элементы управления DataList и Repeater были созданы еще в ASP.NET 1.x, до того, как шаблон обработчика событий предварительного и пост-уровня стал распространенным.
Как и в GridView, одним из вариантов форматирования на основе данных является создание обработчика ItemDataBound
события. Этот обработчик событий будет проверять данные, которые только что были привязаны к DataListItem
или RepeaterItem
, и при необходимости влиять на форматирование элемента управления.
Для элемента управления DataList изменения форматирования для всего элемента можно реализовать с помощью свойств, связанных со DataListItem
стилем , к которым относятся стандартные Font
, ForeColor
, BackColor
, CssClass
и т. д. Чтобы повлиять на форматирование определенных веб-элементов управления в шаблоне DataList, необходимо программно получить доступ к их стилю и изменить их стиль. Мы узнали, как это сделать еще в учебнике Пользовательское форматирование на основе данных . Как и элемент управления Repeater, класс не имеет свойств, RepeaterItem
связанных со стилем, поэтому все связанные со стилем изменения, внесенные RepeaterItem
в ItemDataBound
в обработчике событий, должны выполняться программным путем доступа к веб-элементам управления в шаблоне и их обновления.
ItemDataBound
Так как методы форматирования для DataList и Repeater практически идентичны, в нашем примере мы сосредоточимся на использовании DataList.
Шаг 1. Отображение сведений о продукте в dataList
Прежде чем мы рассмотрим форматирование, сначала создадим страницу, которая использует DataList для отображения сведений о продукте. В предыдущем руководстве мы создали DataList, в котором ItemTemplate
отображалось название, категория, поставщик, количество на единицу и цена каждого продукта. Давайте повторим эту функцию в этом руководстве. Для этого можно либо воссоздать DataList и его ObjectDataSource с нуля, либо скопировать эти элементы управления со страницы, созданной в предыдущем руководстве (Basics.aspx
), и вставить их на страницу этого руководства (Formatting.aspx
).
После репликации функциональных возможностей DataList и ObjectDataSource из Basics.aspx
в Formatting.aspx
укажите , чтобы изменить свойство DataList ID
с DataList1
на более описательное ItemDataBoundFormattingExample
. Затем просмотрите Список данных в браузере. Как показано на рисунке 1, единственное различие форматирования между каждым продуктом заключается в том, что цвет фона чередуется.
Рис. 1. Продукты перечислены в элементе управления DataList (щелкните, чтобы просмотреть полноразмерное изображение)
В этом руководстве мы отформатируем Список данных таким образом, чтобы все продукты с ценой менее 20,00 долл. США были выделены желтым цветом как название, так и цена за единицу.
Шаг 2. Программное определение значения данных в обработчике событий ItemDataBound
Так как только те продукты с ценой ниже $ 20,00 будут иметь пользовательское форматирование применено, мы должны быть в состоянии определить цену каждого продукта. При привязке данных к DataList DataList перечисляет записи в источнике данных и для каждой DataListItem
записи создает экземпляр , привязывая запись источника данных к DataListItem
. После привязки данных конкретной записи к текущему DataListItem
объекту запускается событие DataList ItemDataBound
. Мы можем создать обработчик событий для этого события, чтобы проверить значения данных для текущего DataListItem
и на основе этих значений внести необходимые изменения в форматирование.
Создайте ItemDataBound
событие для DataList и добавьте следующий код:
protected void ItemDataBoundFormattingExample_ItemDataBound
(object sender, DataListItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
// Programmatically reference the ProductsRow instance bound
// to this DataListItem
Northwind.ProductsRow product =
(Northwind.ProductsRow)((System.Data.DataRowView)e.Item.DataItem).Row;
// See if the UnitPrice is not NULL and less than $20.00
if (!product.IsUnitPriceNull() && product.UnitPrice < 20)
{
// TODO: Highlight the product's name and price
}
}
}
Хотя концепция и семантика обработчика событий DataList ItemDataBound
те же, что и те, которые используются обработчиком событий GridView RowDataBound
в учебнике Пользовательское форматирование на основе данных , синтаксис немного отличается. При возникновении события только что привязанный к данным передается в соответствующий e.Row
обработчик событий через e.Item
(вместо , как в случае с обработчиком событий GridViewRowDataBound
).ItemDataBound
DataListItem
Обработчик событий DataList ItemDataBound
срабатывает для каждой строки, добавленной в DataList, включая строки заголовков, нижних колонтитулов и строки разделителей. Однако сведения о продукте привязаны только к строкам данных. Поэтому при использовании ItemDataBound
события для проверки данных, привязанных к DataList, необходимо сначала убедиться, что мы работаем с элементом данных. Это можно сделать, проверив DataListItem
свойство sItemType
, которое может иметь одно из следующих восьми значений:
AlternatingItem
EditItem
Footer
Header
Item
Pager
SelectedItem
Separator
Элементы Item
данных DataList в и AlternatingItem``DataListItem
. При условии, что мы работаем с или AlternatingItem
, мы имеем Item
доступ к фактическому ProductsRow
экземпляру, который был привязан к текущему DataListItem
объекту . Свойство DataListItem
s DataItem
содержит ссылку на DataRowView
объект , свойство которого Row
предоставляет ссылку на фактический ProductsRow
объект .
Далее мы проверка ProductsRow
свойство экземпляра UnitPrice
. Так как поле таблицы UnitPrice
Products допускает NULL
значения, прежде чем пытаться получить доступ к свойствуUnitPrice
, необходимо сначала проверка, чтобы узнать, имеет NULL
ли оно значение с помощью IsUnitPriceNull()
метода . UnitPrice
Если значение не NULL
равно , мы проверка, чтобы проверить, меньше ли оно 20,00 долл. США. Если оно действительно ниже 20,00 долл. США, необходимо применить настраиваемое форматирование.
Шаг 3. Выделение названия и цены продукта
Как только мы знаем, что цена продукта менее $ 20,00, все, что остается, это выделить его название и цену. Для этого сначала необходимо программно сослаться на элементы управления Label в , ItemTemplate
отображающие название и цену продукта. Затем нам нужно, чтобы они отображали желтый фон. Эти сведения о форматировании можно применить путем непосредственного изменения свойств меток BackColor
(LabelID.BackColor = Color.Yellow
). Однако в идеале все вопросы, связанные с отображением, должны быть выражены с помощью каскадных таблиц стилей. Фактически у нас уже есть таблица стилей, которая предоставляет требуемое форматирование, определенное в Styles.css
- AffordablePriceEmphasis
, которое было создано и описано в руководстве Пользовательское форматирование на основе данных .
Чтобы применить форматирование, просто присвойте свойствам двух веб-элементов управления CssClass
AffordablePriceEmphasis
Label значение , как показано в следующем коде:
// Highlight the product name and unit price Labels
// First, get a reference to the two Label Web controls
Label ProductNameLabel = (Label)e.Item.FindControl("ProductNameLabel");
Label UnitPriceLabel = (Label)e.Item.FindControl("UnitPriceLabel");
// Next, set their CssClass properties
if (ProductNameLabel != null)
ProductNameLabel.CssClass = "AffordablePriceEmphasis";
if (UnitPriceLabel != null)
UnitPriceLabel.CssClass = "AffordablePriceEmphasis";
Завершив работу обработчика ItemDataBound
событий, вернитесь на страницу Formatting.aspx
в браузере. Как показано на рисунке 2, для этих продуктов с ценой ниже 20,00 долл. США выделены как название, так и цена.
Рис. 2. Эти продукты менее 20,00 долл. США выделены (щелкните, чтобы просмотреть полноразмерное изображение)
Примечание
Так как DataList отображается в виде HTML <table>
, его DataListItem
экземпляры имеют свойства, связанные со стилем, которые можно задать для применения определенного стиля ко всему элементу. Например, если бы мы хотели выделить весь элемент желтым цветом, если его цена была меньше 20,00 долл. США, можно было бы заменить код, ссылающийся на метки, и задать их CssClass
свойства следующей строкой кода: e.Item.CssClass = "AffordablePriceEmphasis"
(см. рис. 3).
Однако RepeaterItem
элементы , составляющие элемент управления Repeater, не предлагают таких свойств на уровне стиля. Поэтому применение настраиваемого форматирования к Repeater требует применения свойств стиля к веб-элементам управления в шаблонах Repeater, как это было показано на рисунке 2.
Рис. 3. Для продуктов под 20,00 долл. США выделен весь элемент продукта (щелкните, чтобы просмотреть полноразмерное изображение)
Использование функций форматирования из шаблона
В учебнике Использование TemplateFields в элементе управления GridView мы узнали, как использовать функцию форматирования в GridView TemplateField для применения настраиваемого форматирования на основе данных, привязанных к строкам GridView. Функция форматирования — это метод, который может быть вызван из шаблона и возвращает HTML-код, который будет выдан на его месте. Функции форматирования могут находиться в классе кода программной части страницы ASP.NET или могут быть централизованы в файлах классов в папке App_Code
или в отдельном проекте библиотеки классов. Перемещение функции форматирования из класса кода программной части страницы ASP.NET идеально подходит, если вы планируете использовать одну и ту же функцию форматирования на нескольких ASP.NET страницах или в других веб-приложениях ASP.NET.
Чтобы продемонстрировать функции форматирования, пусть сведения о продукте включают текст [DISCONTINUED] рядом с названием продукта, если он не отменен. Кроме того, пусть цена выделена желтым цветом, если она меньше 20,00 долл. США (как это было в ItemDataBound
примере обработчика событий); если цена составляет 20,00 долл. США или выше, пусть не отображает фактическую цену, но вместо этого текст: Вызовите ценовое предложение. На рисунке 4 показан снимок экрана со списком продуктов с примененными правилами форматирования.
Рис. 4. Для дорогих продуктов цена заменена текстом. Вызовите ценовое предложение (щелкните, чтобы просмотреть полноразмерное изображение)
Шаг 1. Создание функций форматирования
В этом примере нам потребуются две функции форматирования: одна отображает название продукта вместе с текстом [DISCONTINUED], если это необходимо, а другая — выделенную цену, если она меньше 20,00 долл. США, или текст . В противном случае вызовите ценовую цену. Создадим эти функции в классе кода программной части страницы ASP.NET и назовем их DisplayProductNameAndDiscontinuedStatus
и DisplayPrice
. Оба метода должны возвращать HTML-код для отрисовки в виде строки, и оба метода должны быть помечены Protected
(или Public
), чтобы вызываться из декларативной части синтаксиса страницы ASP.NET. Ниже приведен код для этих двух методов.
protected string DisplayProductNameAndDiscontinuedStatus
(string productName, bool discontinued)
{
// Return just the productName if discontinued is false
if (!discontinued)
return productName;
else
// otherwise, return the productName appended with the text "[DISCONTINUED]"
return string.Concat(productName, " [DISCONTINUED]");
}
protected string DisplayPrice(Northwind.ProductsRow product)
{
// If price is less than $20.00, return the price, highlighted
if (!product.IsUnitPriceNull() && product.UnitPrice < 20)
return string.Concat("<span class=\"AffordablePriceEmphasis\">",
product.UnitPrice.ToString("C"), "</span>");
else
// Otherwise return the text, "Please call for a price quote"
return "<span>Please call for a price quote</span>";
}
Обратите внимание, что DisplayProductNameAndDiscontinuedStatus
метод принимает значения productName
полей данных и discontinued
в виде скалярных значенийProductsRow
, тогда как DisplayPrice
метод принимает экземпляр (а не скалярное unitPrice
значение). Любой из подходов будет работать; Однако, если функция форматирования работает со скалярными значениями, которые могут содержать значения базы данных NULL
(напримерUnitPrice
, ни ; ни Discontinued
ProductName
допустимые NULL
значения), то при обработке этих скалярных входных данных необходимо проявлять особую осторожность.
В частности, входной параметр должен иметь тип , Object
так как входящее значение может быть экземпляром DBNull
, а не ожидаемым типом данных. Кроме того, необходимо выполнить проверка, чтобы определить, является ли входящее значение значением базы данныхNULL
. То есть, если мы хотим DisplayPrice
, чтобы метод принимал цену в качестве скалярного значения, необходимо использовать следующий код:
protected string DisplayPrice(object unitPrice)
{
// If price is less than $20.00, return the price, highlighted
if (!Convert.IsDBNull(unitPrice) && ((decimal) unitPrice) < 20)
return string.Concat("<span class=\"AffordablePriceEmphasis\">",
((decimal) unitPrice).ToString("C"), "</span>");
else
// Otherwise return the text, "Please call for a price quote"
return "<span>Please call for a price quote</span>";
}
Обратите внимание, что unitPrice
входной параметр имеет тип Object
и что условный оператор был изменен, чтобы определить, является ли unitPrice
он DBNull
или нет. Кроме того, так как unitPrice
входной параметр передается в виде Object
, он должен быть приведен к десятичному значению.
Шаг 2. Вызов функции форматирования из элемента ItemTemplate dataList
После добавления функций форматирования в класс кода программной части страницы ASP.NET остается только вызвать эти функции форматирования из dataList .ItemTemplate
Чтобы вызвать функцию форматирования из шаблона, разместите вызов функции в синтаксисе привязки данных:
<%# MethodName(inputParameter1, inputParameter2, ...) %>
В элементе управления Метка Веб-элемент управления DataList ItemTemplate
ProductNameLabel
в настоящее время отображает имя продукта, присваивая его Text
свойству результат <%# Eval("ProductName") %>
. Чтобы в нем отображалось имя плюс текст [DISCONTINUED], при необходимости обновите декларативный синтаксис, чтобы вместо этого присвоить Text
свойству значение DisplayProductNameAndDiscontinuedStatus
метода . При этом необходимо передать имя продукта и неподдерживаемые значения с помощью синтаксиса Eval("columnName")
. Eval
возвращает значение типа Object
, но DisplayProductNameAndDiscontinuedStatus
метод ожидает входные параметры типа String
и Boolean
; поэтому необходимо привести значения, возвращаемые методом, к ожидаемым типам Eval
входных параметров, например:
<h4>
<asp:Label ID="ProductNameLabel" runat="server"
Text='<%# DisplayProductNameAndDiscontinuedStatus((string) Eval("ProductName"),
(bool) Eval("Discontinued")) %>'>
</asp:Label>
</h4>
Чтобы отобразить цену, можно просто присвоить UnitPriceLabel
свойству Label s Text
значение, возвращаемое методом DisplayPrice
, так же, как и для отображения названия продукта и текста [DISCONTINUED]. Однако вместо передачи в UnitPrice
качестве скалярного входного параметра мы передадим весь ProductsRow
экземпляр :
<asp:Label ID="UnitPriceLabel" runat="server"
Text='<%# DisplayPrice((Northwind.ProductsRow)
((System.Data.DataRowView) Container.DataItem).Row) %>'>
</asp:Label>
При вызове функций форматирования уделите некоторое время, чтобы просмотреть ход выполнения в браузере. Ваш экран должен выглядеть примерно так же, как на рис. 5, с неподдерживаемых продуктов, включая текст [DISCONTINUED] и продукты стоимостью более 20,00 долл. США с заменой на текст Пожалуйста, вызовите цену.
Рис. 5. Для дорогих продуктов цена заменена текстом. Вызовите ценовое предложение (щелкните, чтобы просмотреть полноразмерное изображение)
Сводка
Форматирование содержимого элемента управления DataList или Repeater на основе данных можно выполнить двумя способами. Первый способ — создать обработчик событий для ItemDataBound
события, который срабатывает при привязке каждой записи в источнике данных к новому DataListItem
объекту или RepeaterItem
. В обработчике ItemDataBound
событий можно проверить данные текущего элемента, а затем применить форматирование к содержимому шаблона или ко DataListItem
всему элементу.
Кроме того, пользовательское форматирование можно реализовать с помощью функций форматирования. Функция форматирования — это метод, который можно вызвать из шаблонов DataList или Repeater, который возвращает HTML для выдачи на его месте. Часто HTML-код, возвращаемый функцией форматирования, определяется значениями, привязанными к текущему элементу. Эти значения можно передать в функцию форматирования в виде скалярных значений или путем передачи всего объекта, привязанного к элементу (например, экземпляру ProductsRow
).
Счастливого программирования!
Об авторе
Скотт Митчелл( Scott Mitchell), автор семи книг ASP/ASP.NET и основатель 4GuysFromRolla.com, работает с веб-технологиями Майкрософт с 1998 года. Скотт работает независимым консультантом, тренером и писателем. Его последняя книга Sams Teach Yourself ASP.NET 2.0 в 24 часах. Он может быть доступен в mitchell@4GuysFromRolla.com. или через его блог, который можно найти по адресу http://ScottOnWriting.NET.
Особая благодарность
Эта серия учебников была рассмотрена многими полезными рецензентами. Ведущим рецензентом этого руководства были Яаков Эллис, Рэнди Шмидт и Лиз Шулок. Хотите просмотреть предстоящие статьи MSDN? Если да, опустите мне строку на mitchell@4GuysFromRolla.com.