Заметка
Доступ к этой странице требует авторизации. Вы можете попробовать войти в систему или изменить каталог.
Доступ к этой странице требует авторизации. Вы можете попробовать сменить директорию.
В этом руководстве мы рассмотрим примеры форматирования внешнего вида элементов управления DataList и Repeater, используя функции форматирования в шаблонах или обрабатывая событие DataBound.
Введение
Как мы видели в предыдущем руководстве, DataList предлагает ряд свойств, связанных с стилем, которые влияют на его внешний вид. В частности, мы узнали, как назначить классы CSS по умолчанию свойствам DataList HeaderStyle, ItemStyle, AlternatingItemStyle и SelectedItemStyle. Помимо этих четырех свойств, DataList включает ряд других свойств, связанных со стилем, таких как Font, ForeColorBackColorи 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 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 в руководстве по пользовательским форматированиям на основе данных , синтаксис немного отличается.
ItemDataBound При срабатывании события DataListItem, только что привязанный к данным объект передается в соответствующий обработчик e.Item (вместо обработчика e.Row событий GridViewRowDataBound). Обработчик событий DataList ItemDataBound строки, добавленной в DataList, включая строки верхнего колонтитула и строки разделителя. Однако сведения о продукте привязаны только к строкам данных. Поэтому при использовании ItemDataBound события для проверки данных, привязанных к DataList, необходимо сначала убедиться, что мы работаем с элементом данных. Это можно сделать, проверив DataListItem свойство sItemType, которое может иметь одно из следующих восьми значений:
AlternatingItemEditItemFooterHeaderItemPagerSelectedItemSeparator
И то Item, и другое AlternatingItem``DataListItem составляют элементы данных DataList. Предполагая, что мы работаем с Item или AlternatingItem, мы получаем доступ к фактическому экземпляру ProductsRow, привязанному к текущему DataListItem. Свойство DataListItem s DataItem содержит ссылку на DataRowView объект, свойство которого Row предоставляет ссылку на фактический ProductsRow объект.
Затем мы проверяем свойство экземпляра ProductsRowUnitPrice . Так как поле таблицы 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
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 не предоставляют такие свойства уровня стиля. Поэтому применение настраиваемого форматирования к повторителу требует применения свойств стиля к веб-элементам управления в шаблонах Повторителя, как и на рис. 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 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 скалярные значения, а DisplayPrice метод принимает ProductsRow экземпляр (а не unitPrice скалярное значение). Любой из подходов будет работать; однако, если функция форматирования работает со скалярными значениями, которые могут содержать значения базы данных NULL (например, UnitPrice, ни ProductName, ни Discontinued не допускают 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, и условное выражение было изменено, чтобы установить, является ли unitPriceDBNull или нет. Кроме того, так как входной unitPrice параметр передается в виде Object, его необходимо преобразовать в десятичное значение.
Шаг 2. Вызов функции форматирования из шаблона элемента DataList в ItemTemplate
Теперь, когда функции форматирования добавлены в класс кода ASP.NET страницы, осталось только вызвать эти функции форматирования из DataList ItemTemplate. Чтобы вызвать функцию форматирования из шаблона, поместите вызов функции в синтаксисе привязки данных:
<%# MethodName(inputParameter1, inputParameter2, ...) %>
В элементе управления DataList ItemTemplateProductNameLabel в настоящее время отображается имя продукта, назначив его 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.