Использование TemplateField в элементе управления DetailsView (VB)
Те же возможности TemplateFields, доступные в GridView, также доступны с помощью элемента управления DetailsView. В этом руководстве мы будем отображать один продукт за раз с помощью DetailsView, содержащего TemplateFields.
Введение
TemplateField обеспечивает более высокую степень гибкости при отрисовке данных, чем элементы управления "BoundField", "CheckBoxField", "HyperLinkField" и "Другие элементы управления полями данных". В предыдущем руководстве мы рассмотрели использование TemplateField в GridView:
- Отображение нескольких значений поля данных в одном столбце. В частности, оба
FirstName
LastName
поля были объединены в один столбец GridView. - Используйте альтернативный веб-элемент управления для выражения значения поля данных. Мы узнали, как отобразить
HiredDate
значение с помощью элемента управления Calendar. - Отображение сведений о состоянии на основе базовых данных.
Employees
Хотя таблица не содержит столбец, возвращающий количество дней, которые сотрудник был на задании, мы смогли отобразить такие сведения в примере GridView в предыдущем руководстве с использованием метода TemplateField и форматирования.
Те же возможности TemplateFields, доступные в GridView, также доступны с помощью элемента управления DetailsView. В этом руководстве мы отобразим один продукт за раз с помощью DetailsView, содержащего два templateFields. Первый templateField объединяет UnitPrice
UnitsInStock
поля данных и UnitsOnOrder
поля данных в одну строку DetailsView. Второй templateField отобразит значение Discontinued
поля, но будет использовать метод форматирования для отображения "ДА", если Discontinued
есть True
, и "НЕТ" в противном случае.
Рис. 1. Для настройки отображения используется два шаблона (щелкните, чтобы просмотреть изображение полного размера)
Приступим.
Шаг 1. Привязка данных к DetailsView
Как описано в предыдущем руководстве, при работе с TemplateFields часто проще всего начать с создания элемента управления DetailsView, содержащего только BoundFields, а затем добавить новые templateFields или преобразовать существующие BoundFields в TemplateFields по мере необходимости. Поэтому запустите это руководство, добавив DetailsView на страницу через конструктор и привязав его к ObjectDataSource, который возвращает список продуктов. Эти действия создадут DetailsView с BoundFields для каждого поля, отличного от логического значения продукта, и CheckBoxField для одного логического поля (прекращено).
Откройте страницу и перетащите DetailsViewTemplateField.aspx
DetailsView из панели элементов в конструктор. В смарт-теге DetailsView выберите добавить новый элемент управления ObjectDataSource, который вызывает ProductsBLL
метод класса GetProducts()
.
Рис. 2. Добавление нового элемента управления ObjectDataSource, вызывающего GetProducts()
метод (щелкните, чтобы просмотреть изображение полного размера)
Для этого отчета удалите ProductID
, SupplierID
CategoryID
и ReorderLevel
BoundFields. Затем переупорядочение полей BoundFields, чтобы CategoryName
и SupplierName
BoundFields отображались сразу после ProductName
BoundField. Вы можете настроить HeaderText
свойства и свойства форматирования для BoundFields по мере необходимости. Как и в GridView, эти изменения на уровне BoundField можно выполнять через диалоговое окно "Поля" (доступно, щелкнув ссылку "Изменить поля" в смарт-теге DetailsView) или с помощью декларативного синтаксиса. Наконец, удалите значения сведений и Width
свойств DetailsView, чтобы разрешить элементу управления DetailsView Height
развернуться на основе отображаемых данных и проверить флажок "Включить разбиение на страницы" в смарт-теге.
После внесения этих изменений декларативная разметка элемента управления DetailsView должна выглядеть следующим образом:
<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" AllowPaging="True"
EnableViewState="False">
<Fields>
<asp:BoundField DataField="ProductName" HeaderText="Product"
SortExpression="ProductName" />
<asp:BoundField DataField="CategoryName" HeaderText="Category"
ReadOnly="True" SortExpression="CategoryName" />
<asp:BoundField DataField="SupplierName" HeaderText="Supplier"
ReadOnly="True" SortExpression="SupplierName" />
<asp:BoundField DataField="QuantityPerUnit"
HeaderText="Qty/Unit" SortExpression="QuantityPerUnit" />
<asp:BoundField DataField="UnitPrice" HeaderText="Price"
SortExpression="UnitPrice" />
<asp:BoundField DataField="UnitsInStock"
HeaderText="Units In Stock" SortExpression="UnitsInStock" />
<asp:BoundField DataField="UnitsOnOrder"
HeaderText="Units On Order" SortExpression="UnitsOnOrder" />
<asp:CheckBoxField DataField="Discontinued"
HeaderText="Discontinued" SortExpression="Discontinued" />
</Fields>
</asp:DetailsView>
Просмотрите страницу через браузер. На этом этапе вы увидите один продукт в списке (Chai) с строками с именем продукта, категорией, поставщиком, ценой, единицами в акции, единицами по заказу и его прекращенным состоянием.
Рис. 3. Сведения о продукте показаны с помощью ряда BoundFields (щелкните для просмотра полного размера изображения)
Шаг 2. Объединение цен, единиц акций и единиц по заказу в одну строку
В DetailsView есть строка для UnitPrice
UnitsInStock
полей и UnitsOnOrder
полей. Эти поля данных можно объединить в одну строку с TemplateField, добавив новый ШаблонФилд или преобразовав один из существующих UnitPrice
полей и UnitsInStock
UnitsOnOrder
BoundFields в TemplateField. Хотя я лично предпочитаю преобразование существующих BoundFields, давайте добавим новый TemplateField.
Начните, щелкнув ссылку "Изменить поля" в смарт-теге DetailsView, чтобы открыть диалоговое окно "Поля". Затем добавьте новый templateField и задайте для его HeaderText
свойства значение "Цена и инвентаризация" и переместите новый TemplateField, чтобы он был расположен над UnitPrice
BoundField.
Рис. 4. Добавление нового templateField в элемент управления DetailsView (щелкните, чтобы просмотреть изображение полного размера)
Так как этот новый templateField будет содержать значения, отображаемые в настоящее время в UnitPrice
UnitsInStock
,и UnitsOnOrder
BoundFields, давайте удалите их.
Последней задачей этого шага является определение ItemTemplate
разметки для поля "Цена и инвентаризация", которое можно выполнить либо с помощью интерфейса редактирования шаблона DetailsView в конструкторе, либо с помощью декларативного синтаксиса элемента управления. Как и в GridView, доступ к интерфейсу редактирования шаблона DetailsView можно получить, щелкнув ссылку "Изменить шаблоны" в смарт-теге. Здесь вы можете выбрать шаблон для редактирования из раскрывающегося списка, а затем добавить все веб-элементы управления из панели элементов.
Для этого руководства начните с добавления элемента управления Label в шаблон ItemTemplate
"Цена и инвентаризация". Затем щелкните ссылку "Изменить DataBindings" из смарт-тега веб-элемента управления Label и привязите Text
свойство к UnitPrice
полю.
Рис. 5. Привязка свойства метки Text
к UnitPrice
полю данных (щелкните, чтобы просмотреть изображение полного размера)
Форматирование цены в виде валюты
С этим дополнением веб-элемент управления Label Web control Price and Inventory TemplateField теперь будет отображать только цену выбранного продукта. На рисунке 6 показан снимок экрана нашего прогресса до сих пор при просмотре через браузер.
Рис. 6. Шаблон цены и инвентаризации показывает цену (щелкните, чтобы просмотреть изображение полного размера)
Обратите внимание, что цена продукта не форматируется как валюта. При использовании BoundField форматирование возможно, задав свойству HtmlEncode
значение False
и свойству DataFormatString
{0:formatSpecifier}
. Однако для TemplateField все инструкции по форматированию должны быть указаны в синтаксисе привязки данных или с помощью метода форматирования, определенного где-то в коде приложения (например, в классе кода ASP.NET страницы).
Чтобы указать форматирование синтаксиса привязки данных, используемого в веб-элементе управления Label, вернитесь в диалоговое окно DataBindings, щелкнув ссылку "Изменить dataBindings" из смарт-тега Метки. Инструкции по форматированию можно ввести непосредственно в раскрывающемся списке "Формат" или выбрать одну из определенных строк форматирования. Как и свойство BoundField DataFormatString
, форматирование указывается с помощью {0:formatSpecifier}
.
UnitPrice
Для поля используется форматирование валют, указанное путем выбора соответствующего раскрывающегося списка или ввода {0:C}
вручную.
Рис. 7. Форматирование цены в виде валюты (щелкните, чтобы просмотреть изображение полного размера)
Декларативно спецификация форматирования указывается как второй параметр в Bind
или Eval
методы. Параметры, только что выполненные с помощью конструктора, приводят к следующему выражению привязки данных в декларативной разметке:
<asp:Label ID="Label1" runat="server" Text='<%# Eval("UnitPrice", "{0:C}") %>'/>
Добавление оставшихся полей данных в TemplateField
На этом этапе мы отображали и отформатировали UnitPrice
поле данных в поле Price and Inventory TemplateField, но по-прежнему необходимо отобразить UnitsInStock
поля и UnitsOnOrder
поля. Давайте отобразим их на строке ниже цены и в скобках. В интерфейсе редактирования шаблона в конструкторе такие разметки можно добавить, разместив курсор в шаблоне и просто введя текст для отображения. Кроме того, эту разметку можно ввести непосредственно в декларативном синтаксисе.
Добавьте статическую разметку, веб-элементы управления метками и синтаксис привязки данных, чтобы в шаблоне Price и InventoryField отображались такие сведения о ценах и инвентаризации:
UnitPrice
(в акции / по заказу: unitsInStock / unitsOnOrder)
После выполнения этой задачи декларативная разметка DetailsView должна выглядеть следующим образом:
<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" AllowPaging="True"
EnableViewState="False">
<Fields>
<asp:BoundField DataField="ProductName"
HeaderText="Product" SortExpression="ProductName" />
<asp:BoundField DataField="CategoryName" HeaderText="Category"
ReadOnly="True" SortExpression="CategoryName" />
<asp:BoundField DataField="SupplierName"
HeaderText="Supplier" ReadOnly="True"
SortExpression="SupplierName" />
<asp:BoundField DataField="QuantityPerUnit"
HeaderText="Qty/Unit" SortExpression="QuantityPerUnit" />
<asp:TemplateField HeaderText="Price and Inventory">
<ItemTemplate>
<asp:Label ID="Label1" runat="server"
Text='<%# Eval("UnitPrice", "{0:C}") %>'></asp:Label>
<br />
<strong>
(In Stock / On Order: </strong>
<asp:Label ID="Label2" runat="server"
Text='<%# Eval("UnitsInStock") %>'></asp:Label>
<strong>/</strong>
<asp:Label ID="Label3" runat="server"
Text='<%# Eval("UnitsOnOrder") %>'>
</asp:Label><strong>)</strong>
</ItemTemplate>
</asp:TemplateField>
<asp:CheckBoxField DataField="Discontinued"
HeaderText="Discontinued" SortExpression="Discontinued" />
</Fields>
</asp:DetailsView>
С этими изменениями мы объединили сведения о ценах и инвентаризации в одну строку DetailsView.
Рис. 8. Сведения о ценах и инвентаризации отображаются в одной строке (щелкните, чтобы просмотреть изображение полного размера)
Шаг 3. Настройка сведений об отключенных полях
Столбец Products
таблицы Discontinued
представляет собой битовое значение, указывающее, был ли продукт прекращен. При привязке DetailsView (или GridView) к элементу управления источниками данных поля логических значений, например Discontinued
, реализуются как CheckBoxFields, а поля значений, не являющиеся логическими, например ProductID
, ProductName
и т. д., реализуются как BoundFields. Флажок CheckBoxField отображается как отключенный флажок, который проверяется, имеет ли значение поля данных значение True и снято в противном случае.
Вместо отображения CheckBoxField может потребоваться отобразить текст, указывающий, прекращен ли продукт. Для этого можно удалить CheckBoxField из DetailsView, а затем добавить BoundField, свойство которого DataField
было задано Discontinued
. Сделайте это на некоторое время. После этого изменения DetailsView отображает текст "True" для неподдерживаемых продуктов и false для продуктов, которые по-прежнему активны.
Рис. 9. Строки true и false используются для отображения прекращенного состояния (щелкните для просмотра полного размера изображения)
Представьте, что мы не хотели использовать строки True или False, но "ДА" и "НЕТ" вместо этого. Такая настройка может выполняться с помощью templateField и метода форматирования. Метод форматирования может принимать любое количество входных параметров, но должен возвращать HTML -код (в виде строки), чтобы внедрить его в шаблон.
Добавьте метод форматирования в DetailsViewTemplateField.aspx
класс кода страницы с именем DisplayDiscontinuedAsYESorNO
, который принимает Northwind.ProductsRow
объект в качестве входного параметра и возвращает строку. Как описано в предыдущем руководстве, этот метод должен быть помечен как Protected
или Public
доступен из шаблона.
Protected Function DisplayDiscontinuedAsYESorNO(discontinued As Boolean) As String
If discontinued Then
Return "YES"
Else
Return "NO"
End If
End Function
Этот метод проверяет входной параметр (discontinued
) и возвращает значение "ДА", если оно имеет значение True
"НЕТ" в противном случае.
Примечание.
В методе форматирования, рассмотренном в предыдущем руководстве, мы передавали поле данных, которое может содержать NULL
и поэтому необходимо проверить, имеет ли значение свойства сотрудника HiredDate
значение базы данных NULL
перед доступом к EmployeesRow
HiredDate
свойству. Такая проверка не требуется, так как Discontinued
столбец никогда не может назначать значения базы данных NULL
. Кроме того, именно поэтому метод может принимать логический входной параметр, а не ProductsRow
принимать экземпляр или параметр типа Object
.
После завершения этого метода форматирования все, что остается, — вызвать его из TemplateField ItemTemplate
. Чтобы создать TemplateField, удалите Discontinued
BoundField и добавьте новый TemplateField или преобразуйте Discontinued
BoundField в TemplateField. Затем в декларативном представлении разметки измените шаблонField, чтобы он содержал только элемент ItemTemplate, вызывающий DisplayDiscontinuedAsYESorNO
метод, передав значение свойства текущего ProductRow
экземпляра Discontinued
. К этому доступу можно получить с помощью Eval
метода. В частности, разметка TemplateField должна выглядеть следующим образом:
<asp:TemplateField HeaderText="Discontinued" SortExpression="Discontinued">
<ItemTemplate>
<%#DisplayDiscontinuedAsYESorNO(Convert.ToBoolean(Eval("Discontinued")))%>
</ItemTemplate>
</asp:TemplateField>
Это приведет к вызову DisplayDiscontinuedAsYESorNO
метода при отрисовке DetailsView, передавая ProductRow
значение экземпляра Discontinued
. Eval
Так как метод возвращает значение типаObject
, но DisplayDiscontinuedAsYESorNO
метод ожидает входной параметр типаBoolean
, мы приведение Eval
возвращаемого значения Boolean
методов. Затем DisplayDiscontinuedAsYESorNO
метод возвращает значение "ДА" или "НЕТ" в зависимости от получаемого значения. Возвращаемое значение — это то, что отображается в этой строке DetailsView (см. рис. 10).
Рис. 10. Значения "ДА" или "НЕТ" теперь отображаются в строке "Прекращено" (щелкните, чтобы просмотреть изображение полного размера)
Итоги
TemplateField в элементе управления DetailsView обеспечивает более высокую степень гибкости отображения данных, чем доступно с другими элементами управления полями, и идеально подходит для ситуаций, когда:
- Несколько полей данных должны отображаться в одном столбце GridView
- Данные лучше всего выражены с помощью веб-элемента управления, а не обычного текста
- Выходные данные зависят от базовых данных, таких как отображение метаданных или переформатирование данных
Хотя TemplateFields обеспечивает большую гибкость при отрисовке базовых данных DetailsView, выходные данные DetailsView по-прежнему чувствуют себя немного прямоугольниками, так как каждое поле отображается как строка в HTML <table>
.
Элемент управления FormView обеспечивает большую степень гибкости при настройке отрисованных выходных данных. FormView не содержит поля, а лишь ряд шаблонов (ItemTemplate
, EditItemTemplate
и HeaderTemplate
т. д.). Мы посмотрим, как использовать FormView для получения еще большего контроля над отрисованным макетом в следующем руководстве.
Счастливое программирование!
Об авторе
Скотт Митчелл, автор семи книг ASP/ASP.NET и основатель 4GuysFromRolla.com, работает с технологиями Microsoft Web с 1998 года. Скотт работает независимым консультантом, тренером и писателем. Его последняя книга Сэмс Учит себя ASP.NET 2.0 в 24 часах. Он может быть достигнут в mitchell@4GuysFromRolla.com. или через его блог, который можно найти на http://ScottOnWriting.NET.
Особое спасибо
Эта серия учебников была проверена многими полезными рецензентами. Ведущий рецензент этого руководства — Дэн Джагерс. Хотите просмотреть мои предстоящие статьи MSDN? Если да, упадите меня линию в mitchell@4GuysFromRolla.com.