Поделиться через


Форматирование элементов управления DataList и Repeater в зависимости от данных (VB)

Скотт Митчелл

Загрузить PDF-файл

В этом руководстве мы рассмотрим примеры форматирования внешнего вида элементов управления 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.

  1. Срабатывает событие DataList DataBinding

  2. Данные привязаны к DataList

    Для каждой записи в источнике данных

    1. Создание DataListItem объекта
    2. Сожмите ItemCreated событие
    3. Привяжите запись к DataListItem
    4. Сожмите ItemDataBound событие
    5. Добавление в DataListItem коллекцию Items

При привязке данных к элементу управления Repeater выполняется та же последовательность шагов. Единственное отличие заключается в том, что вместо создаваемых DataListItem экземпляров repeater использует RepeaterItems.

Примечание

Проницательный читатель, возможно, заметил небольшую аномалию между последовательностью шагов, которые выполняются, когда 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, единственное различие форматирования между каждым продуктом заключается в том, что цвет фона чередуется.

Продукты перечислены в элементе управления DataList

Рис. 1. Продукты перечислены в элементе управления DataList (щелкните, чтобы просмотреть полноразмерное изображение)

В этом руководстве мы отформатируем Список данных таким образом, чтобы все продукты с ценой менее 20,00 долл. США были выделены желтым цветом как название, так и цена за единицу.

Шаг 2. Программное определение значения данных в обработчике событий ItemDataBound

Так как только те продукты с ценой ниже $ 20,00 будут иметь пользовательское форматирование применено, мы должны быть в состоянии определить цену каждого продукта. При привязке данных к DataList DataList перечисляет записи в источнике данных и для каждой DataListItem записи создает экземпляр , привязывая запись источника данных к DataListItem. После привязки данных конкретной записи к текущему DataListItem объекту запускается событие DataList ItemDataBound . Мы можем создать обработчик событий для этого события, чтобы проверить значения данных для текущего 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 в учебнике Пользовательское форматирование на основе данных , синтаксис немного отличается. При возникновении события только что привязанный к данным передается в соответствующий e.Rowобработчик событий через e.Item (вместо , как в случае с обработчиком событий GridViewRowDataBound).ItemDataBoundDataListItem Обработчик событий 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, которое было создано и описано в руководстве Пользовательское форматирование на основе данных .

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

' 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 долл. США выделены как название, так и цена.

Эти продукты менее 20,00 долл. США выделены

Рис. 2. Эти продукты менее 20,00 долл. США выделены (щелкните, чтобы просмотреть полноразмерное изображение)

Примечание

Так как DataList отображается в виде HTML <table>, его DataListItem экземпляры имеют свойства, связанные со стилем, которые можно задать для применения определенного стиля ко всему элементу. Например, если бы мы хотели выделить весь элемент желтым цветом, если его цена была меньше 20,00 долл. США, можно было бы заменить код, ссылающийся на метки, и задать их CssClass свойства следующей строкой кода: e.Item.CssClass = "AffordablePriceEmphasis" (см. рис. 3).

Однако RepeaterItem элементы , составляющие элемент управления Repeater, не предлагают таких свойств на уровне стиля. Поэтому применение настраиваемого форматирования к Repeater требует применения свойств стиля к веб-элементам управления в шаблонах Repeater, как это было показано на рисунке 2.

Весь элемент продукта выделен для продуктов до 20,00 долл. США

Рис. 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 показан снимок экрана со списком продуктов с примененными правилами форматирования.

Снимок экрана: продукты, перечисленные в элементе управления DataList, с ценой продуктов стоимостью более 20,00 долл. США, замененной текстом

Рис. 4. Для дорогих продуктов значение Price is Replaced with the Text, Please call for a price quote (Щелкните для просмотра полноразмерного изображения)

Шаг 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 в виде скалярных значенийProductsRow, а DisplayPrice метод принимает экземпляр (а не скалярное 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. Вызов функции форматирования из элемента ItemTemplate в DataList

С помощью функций форматирования, добавленных в класс кода программной части страницы ASP.NET, остается только вызвать эти функции форматирования из dataList ItemTemplate. Чтобы вызвать функцию форматирования из шаблона, поместите вызов функции в синтаксис привязки данных:

<%# MethodName(inputParameter1, inputParameter2, ...) %>

В dataList ItemTemplateProductNameLabel элемент управления Label Web в настоящее время отображает название продукта, назначая его 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 свойству Labels Text значение, возвращаемое методом DisplayPrice , как и для отображения названия продукта и текста [DISCONTINUED]. Однако вместо передачи в UnitPrice качестве скалярного входного параметра мы передаем весь ProductsRow экземпляр :

<asp:Label ID="UnitPriceLabel" runat="server"
    Text='<%# DisplayPrice((Northwind.ProductsRow)
          ((System.Data.DataRowView) Container.DataItem).Row) %>'>
</asp:Label>

После выполнения вызовов функций форматирования просмотрите ход выполнения в браузере. Ваш экран должен выглядеть примерно так, как на рис. 5, с неподдерживаемых продуктов, включая текст [ПРЕКРАЩЕНО], и те продукты стоимостью более 20,00 долл. США, цена которых заменена текстом Пожалуйста, позвоните для предложения цены .

Снимок экрана: продукты, перечисленные в элементе управления DataList, где цена продуктов стоимостью более 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.