Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этом руководстве мы рассмотрим примеры форматирования внешнего вида элементов управления DataList и Repeater, используя функции форматирования в шаблонах или обрабатывая событие DataBound.
Введение
Как мы видели в предыдущем руководстве, DataList предлагает ряд свойств, связанных с стилем, которые влияют на его внешний вид. В частности, мы узнали, как назначить классы CSS по умолчанию свойствам DataList HeaderStyle
, ItemStyle
, AlternatingItemStyle
и SelectedItemStyle
. Помимо этих четырех свойств, DataList включает ряд других свойств, связанных со стилем, таких как Font
, ForeColor
BackColor
и BorderWidth
, чтобы назвать несколько. Элемент управления 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
вместо создания экземпляров RepeaterItem
.
Замечание
Проницательный читатель может заметить некоторое несоответствие в последовательности шагов, которые происходят, когда DataList и Repeater привязаны к данным, в отличие от того, что происходит, когда GridView привязан к данным. В конце процесса привязки данных GridView инициирует событие DataBound
; однако элементы управления DataList и Repeater не имеют подобных событий. Это связано с тем, что элементы DataList и Repeater были созданы во время выпуска ASP.NET 1.x, до того как шаблон обработчика событий на этапах до и после уровня стал широко распространённым.
Как и в GridView, один из вариантов форматирования на основе данных заключается в создании обработчика событий для ItemDataBound
события. Этот обработчик событий проверяет данные, которые только что привязаны к DataListItem
элементу управления или RepeaterItem
влияют на форматирование элемента управления по мере необходимости.
Для элемента управления DataList изменения форматирования для всего элемента можно реализовать с помощью свойств, относящихся к стилю, которые включают стандартные DataListItem
, Font
, ForeColor
, BackColor
и т. д. Чтобы повлиять на форматирование определенных веб-элементов управления в шаблоне 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
. Затем просмотрите DataList в браузере. Как показано на рисунке 1, единственное различие в форматировании каждого продукта заключается в том, что цвет фона альтернативный.
Рис. 1. Продукты перечислены в элементе управления DataList (щелкните, чтобы просмотреть изображение полного размера)
В этом руководстве давайте отформатируем DataList таким образом, чтобы у всех продуктов с ценой менее $20,00 и название, и цена за единицу были выделены желтым цветом.
Шаг 2. Программное определение значения данных в обработчике событий ItemDataBound
Так как настраиваемые форматы будут применяться только к продуктам с ценой ниже $20,00, мы должны иметь возможность определить цену каждого продукта. При привязке данных к DataList, DataList перечисляет записи в источнике данных и для каждой записи создает экземпляр DataListItem
, привязывая запись источника данных к DataListItem
. После того как данные конкретной записи привязаны к текущему объекту DataListItem
, событие ItemDataBound
DataList запускается. Мы можем создать обработчик для этого события, чтобы проверить значения данных для текущего DataListItem
и, на основе этих значений, внести необходимые изменения в форматирование.
ItemDataBound
Создайте событие для DataList и добавьте следующий код:
Protected Sub ItemDataBoundFormattingExample_ItemDataBound _
(sender As Object, e As DataListItemEventArgs) _
Handles ItemDataBoundFormattingExample.ItemDataBound
If e.Item.ItemType = ListItemType.Item OrElse _
e.Item.ItemType = ListItemType.AlternatingItem Then
' Programmatically reference the ProductsRow instance
' bound to this DataListItem
Dim product As Northwind.ProductsRow = _
CType(CType(e.Item.DataItem, System.Data.DataRowView).Row, _
Northwind.ProductsRow)
' See if the UnitPrice is not NULL and less than $20.00
If Not product.IsUnitPriceNull() AndAlso product.UnitPrice < 20 Then
' TODO: Highlight the product's name and price
End If
End If
End Sub
Хотя концепция и семантика обработчика событий DataList ItemDataBound
совпадают с теми, которые используются обработчиком событий GridView RowDataBound
в руководстве по пользовательским форматированиям на основе данных , синтаксис немного отличается.
ItemDataBound
При срабатывании события DataListItem
, только что привязанный к данным объект передается в соответствующий обработчик e.Item
(вместо обработчика e.Row
событий GridViewRowDataBound
). Обработчик событий DataList ItemDataBound
строки, добавленной в DataList, включая строки верхнего колонтитула и строки разделителя. Однако сведения о продукте привязаны только к строкам данных. Поэтому при использовании ItemDataBound
события для проверки данных, привязанных к DataList, необходимо сначала убедиться, что мы работаем с элементом данных. Это можно сделать, проверив DataListItem
свойство sItemType
, которое может иметь одно из следующих восьми значений:
AlternatingItem
EditItem
Footer
Header
Item
Pager
SelectedItem
Separator
И то Item
, и другое AlternatingItem``DataListItem
составляют элементы данных DataList. Предполагая, что мы работаем с Item
или AlternatingItem
, мы получаем доступ к фактическому экземпляру 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
, которое было создано и рассмотрено в руководстве по настраиваемым форматированиям на основе данных .
Чтобы применить форматирование, просто установите свойства для двух элементов управления Label Web на CssClass
, как показано в следующем коде:
' Highlight the product name and unit price Labels
' First, get a reference to the two Label Web controls
Dim ProductNameLabel As Label = CType(e.Item.FindControl("ProductNameLabel"), Label)
Dim UnitPriceLabel As Label = CType(e.Item.FindControl("UnitPriceLabel"), Label)
' Next, set their CssClass properties
If ProductNameLabel IsNot Nothing Then
ProductNameLabel.CssClass = "AffordablePriceEmphasis"
End If
If UnitPriceLabel IsNot Nothing Then
UnitPriceLabel.CssClass = "AffordablePriceEmphasis"
End If
Завершив выполнение обработчика ItemDataBound
событий, перейдите на Formatting.aspx
страницу в браузере. Как показано на рисунке 2, те продукты, которые стоят меньше $20,00, выделены как по имени, так и по цене.
Рис. 2. Эти продукты меньше $ 20,00 выделены (щелкните, чтобы просмотреть изображение полного размера)
Замечание
Так как DataList отображается как HTML <table>
, его DataListItem
экземпляры имеют свойства, связанные со стилем, которые можно задать для применения определенного стиля ко всему элементу. Например, если мы хотели выделить весь желтый элемент, если его цена была меньше $ 20,00, мы могли бы заменить код, на который ссылались метки и задать их CssClass
свойства со следующей строкой кода: e.Item.CssClass = "AffordablePriceEmphasis"
(см. рис. 3).
Однако элементы RepeaterItem
управления Repeater не предоставляют такие свойства уровня стиля. Поэтому применение настраиваемого форматирования к повторителу требует применения свойств стиля к веб-элементам управления в шаблонах Повторителя, как и на рис. 2.
Рис. 3. Вся единица товара подсвечена для товаров менее 20,00 долл. США (щелкните, чтобы просмотреть изображение в полном размере)
Использование функций форматирования из шаблона
В учебнике «Использование TemplateField элементов в управлении GridView» мы рассмотрели, как применять функцию форматирования внутри TemplateField элемента GridView для настройки форматирования, основанного на данных, привязанных к строкам GridView. Функция форматирования — это метод, который может вызываться из шаблона и возвращает HTML-код, который будет выдаваться на его месте. Функции форматирования могут находиться в классе кода ASP.NET страницы или быть централизованными в файлах классов в папке App_Code
или в отдельном проекте библиотеки классов. Перемещение функции форматирования из класса кода ASP.NET страницы идеально подходит, если вы планируете использовать одну функцию форматирования в нескольких ASP.NET страницах или других веб-приложениях ASP.NET.
Чтобы продемонстрировать функции форматирования, давайте добавим текст [ПРЕКРАЩЕНО] рядом с именем продукта, если он снят с производства. Кроме того, пусть цена выделена желтым цветом, если она меньше $ 20,00 (как мы сделали в ItemDataBound
примере обработчика событий); если цена составляет $ 20,00 или выше, пусть не отображается фактическая цена, а вместо текста, пожалуйста, вызовите ценовую цитату. На рисунке 4 показан снимок экрана списка продуктов с применением этих правил форматирования.
Рис. 4. Для дорогих продуктов цена заменена текстом, обратитесь к ценовой цитате (щелкните, чтобы просмотреть изображение полного размера)
Шаг 1. Создание функций форматирования
В этом примере нам нужны две функции форматирования: одна отображает имя продукта вместе с текстом [ПРЕКРАЩЕНО], при необходимости, и другая функция отображает либо выделенную цену, если она меньше $20,00, либо текст "пожалуйста, позвоните для получения информации о цене" в противном случае. Давайте создадим эти функции в классе кодовой части страницы ASP.NET и назовем их DisplayProductNameAndDiscontinuedStatus
и DisplayPrice
. Оба метода должны возвращать HTML для отрисовки в виде строки, и их необходимо пометить Protected
(или Public
) для вызова из декларативной части синтаксиса страницы ASP.NET. Следующий код для этих двух методов:
Protected Function DisplayProductNameAndDiscontinuedStatus _
(productName As String, discontinued As Boolean) As String
' Return just the productName if discontinued is false
If Not discontinued Then
Return productName
Else
' otherwise, return the productName appended with the text "[DISCONTINUED]"
Return String.Concat(productName, " [DISCONTINUED]")
End If
End Function
Protected Function DisplayPrice(product As Northwind.ProductsRow) As String
' If price is less than $20.00, return the price, highlighted
If Not product.IsUnitPriceNull() AndAlso product.UnitPrice < 20 Then
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>"
End If
End Function
Обратите внимание, что DisplayProductNameAndDiscontinuedStatus
метод принимает значения productName
полей данных как discontinued
скалярные значения, а DisplayPrice
метод принимает ProductsRow
экземпляр (а не unitPrice
скалярное значение). Любой из подходов будет работать; однако, если функция форматирования работает со скалярными значениями, которые могут содержать значения базы данных NULL
(например, UnitPrice
, ни ProductName
, ни Discontinued
не допускают NULL
значений), при обработке этих скалярных входных данных необходимо проявлять особую осторожность.
В частности, входной параметр должен быть типом Object
, так как входящее значение может быть экземпляром DBNull
вместо ожидаемого типа данных. Кроме того, необходимо выполнить проверку, чтобы определить, является ли входящее значение значением базы данных NULL
. То есть если бы мы хотели DisplayPrice
, чтобы метод принял цену как скалярное значение, нам придется использовать следующий код:
Protected Function DisplayPrice(ByVal unitPrice As Object) As String
' If price is less than $20.00, return the price, highlighted
If Not Convert.IsDBNull(unitPrice) AndAlso CType(unitPrice, Decimal) < 20 Then
Return String.Concat("<span class="AffordablePriceEmphasis">", _
CType(unitPrice, Decimal).ToString("C"), "</span>")
Else
' Otherwise return the text, "Please call for a price quote"
Return "<span>Please call for a price quote</span>"
End If
End Function
Обратите внимание, что входной параметр unitPrice
имеет тип Object
, и условное выражение было изменено, чтобы установить, является ли unitPrice
DBNull
или нет. Кроме того, так как входной unitPrice
параметр передается в виде Object
, его необходимо преобразовать в десятичное значение.
Шаг 2. Вызов функции форматирования из шаблона элемента DataList в ItemTemplate
Теперь, когда функции форматирования добавлены в класс кода ASP.NET страницы, осталось только вызвать эти функции форматирования из DataList ItemTemplate
. Чтобы вызвать функцию форматирования из шаблона, поместите вызов функции в синтаксисе привязки данных:
<%# MethodName(inputParameter1, inputParameter2, ...) %>
В элементе управления DataList ItemTemplate
ProductNameLabel
в настоящее время отображается имя продукта, назначив его Text
свойству результат<%# Eval("ProductName") %>
. Чтобы отобразить имя и текст [ОТМЕНА], при необходимости обновите декларативный синтаксис, чтобы вместо этого назначить 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 значение, возвращаемое Text
методом, как мы сделали для отображения имени продукта и текста [ПРЕКРАЩЕНО]. Однако, вместо передачи UnitPrice
в качестве скалярного вводного параметра, мы передаем весь экземпляр ProductsRow
.
<asp:Label ID="UnitPriceLabel" runat="server"
Text='<%# DisplayPrice((Northwind.ProductsRow)
((System.Data.DataRowView) Container.DataItem).Row) %>'>
</asp:Label>
С установленными вызовами функций форматирования потратьте немного времени, чтобы просмотреть наш прогресс в браузере. Экран должен выглядеть примерно так же, как на рис. 5, с продуктами, снятыми с производства, включая текст [ПРЕКРАЩЕНО], а у продуктов стоимостью более $ 20,00 вместо цены будет текст "Позвоните, чтобы получить ценовую информацию".
Рис. 5. Для дорогих товаров цена заменена текстом: позвоните, чтобы узнать цену (щелкните для просмотра изображения в полном размере)
Сводка
Форматирование содержимого управляющего элемента DataList или Repeater в зависимости от данных можно выполнить с помощью двух методов. Первым способом является создание обработчика событий для ItemDataBound
события, который запускается по мере привязки каждой записи в источнике данных к новому DataListItem
или RepeaterItem
. В обработчике ItemDataBound
событий данные текущего элемента можно проверить, а затем форматирование можно применить к содержимому шаблона или к DataListItem
всему элементу.
Кроме того, можно реализовать настраиваемое форматирование с помощью функций форматирования. Функция форматирования — это метод, который можно вызвать из шаблонов DataList или Repeater, возвращающих HTML-код для выдачи на его месте. Часто HTML, возвращаемый функцией форматирования, определяется значениями, привязанными к текущему элементу. Эти значения можно передать в функцию форматирования как скалярные значения, так и путем передачи всего объекта, привязанного к элементу (например, экземпляру ProductsRow
).
Счастливое программирование!
Сведения о авторе
Скотт Митчелл, автор семи книг ASP/ASP.NET и основатель 4GuysFromRolla.com, работает с технологиями Microsoft Web с 1998 года. Скотт работает независимым консультантом, тренером и писателем. Его последняя книга — Sams Teach Yourself ASP.NET 2.0 за 24 часа. С ним можно связаться по адресу mitchell@4GuysFromRolla.com.
Особое спасибо кому
Эта серия учебников была проверена многими полезными рецензентами. Ведущие рецензенты этого руководства были Яаков Эллис, Рэнди Шмидт и Лиз Шулок. Хотите просмотреть мои предстоящие статьи MSDN? Если да, напишите мне на mitchell@4GuysFromRolla.com.