Использование TemplateField в элементе управления DetailsView (C#)
Те же возможности TemplateFields, доступные в GridView, также доступны в элементе управления DetailsView. В этом руководстве мы будем отображать по одному продукту за раз с помощью DetailsView, содержащего TemplateFields.
Введение
TemplateField обеспечивает более высокую степень гибкости при отрисовке данных, чем BoundField, CheckBoxField, HyperLinkField и другие элементы управления поля данных. В предыдущем руководстве мы рассмотрели использование TemplateField в GridView для выполнения следующих задач:
- Отображение нескольких значений полей данных в одном столбце. В частности, поля
FirstName
и былиLastName
объединены в один столбец GridView. - Используйте альтернативный веб-элемент управления для выражения значения поля данных. Мы узнали
HiredDate
, как отобразить значение с помощью элемента управления Календарь. - Отображение сведений о состоянии на основе базовых данных. Хотя таблица
Employees
не содержит столбец, возвращающий количество дней, в течение которых сотрудник был на задании, мы смогли отобразить такие сведения в примере GridView в предыдущем руководстве с помощью templateField и метода форматирования.
Те же возможности TemplateFields, доступные в GridView, также доступны в элементе управления DetailsView. В этом руководстве мы будем отображать по одному продукту за раз с помощью DetailsView, содержащего два TemplateField. Первое поле TemplateField объединит UnitPrice
поля данных , UnitsInStock
и UnitsOnOrder
в одну строку DetailsView. Второе TemplateField будет отображать значение Discontinued
поля, но будет использовать метод форматирования для отображения "ДА", если Discontinued
имеет значение true
, и "НЕТ" в противном случае.
Рис. 1. Для настройки отображения используются два поля шаблона (щелкните для просмотра полноразмерного изображения)
Приступим к работе!
Шаг 1. Привязка данных к DetailsView
Как обсуждалось в предыдущем руководстве, при работе с TemplateFields часто проще всего начать с создания элемента управления DetailsView, содержащего только BoundFields, а затем добавить новые TemplateFields или преобразовать существующие Поля BoundFields в TemplateFields при необходимости. Поэтому для начала работы с этим руководством добавьте DetailsView на страницу с помощью Designer и привязав его к ObjectDataSource, который возвращает список продуктов. Эти действия позволят создать DetailsView с BoundFields для каждого нелогического поля значения продукта и CheckBoxField для одного поля логического значения (Не поддерживается).
Откройте страницу DetailsViewTemplateField.aspx
и перетащите Элемент DetailsView с панели элементов на Designer. В смарт-теге DetailsView выберите добавить новый элемент управления ObjectDataSource, который вызывает ProductsBLL
метод класса GetProducts()
.
Рис. 2. Добавление нового элемента управления ObjectDataSource, который вызывает GetProducts()
метод (щелкните для просмотра полноразмерного изображения)
Для этого отчета удалите ProductID
, SupplierID
, CategoryID
и ReorderLevel
BoundFields. Затем переупорядочение BoundFields, CategoryName
чтобы и SupplierName
BoundFields отображались сразу после ProductName
BoundField. Вы можете настраивать HeaderText
свойства и свойства форматирования для BoundFields по своему умыслу. Как и в GridView, эти изменения на уровне BoundField можно выполнять с помощью диалогового окна Поля (для доступа к ссылке Изменить поля в смарт-теге DetailsView) или декларативного синтаксиса. Наконец, очистите значения свойств DetailsView Height
и Width
, чтобы разрешить элементу управления DetailsView расширяться на основе отображаемых данных и проверка флажок Включить разбиение по страницам в смарт-теге.
После внесения этих изменений декларативная разметка элемента управления 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, добавив новое TemplateField или преобразовав один из существующих UnitPrice
полей , UnitsInStock
и UnitsOnOrder
BoundFields в TemplateField. Хотя я лично предпочитаю преобразовывать существующие BoundFields, давайте попрактиковаемся, добавив новое TemplateField.
Для начала щелкните ссылку Изменить поля в смарт-теге DetailsView, чтобы открыть диалоговое окно Поля. Затем добавьте новое templateField и задайте для его HeaderText
свойства значение "Price and Inventory" (Цена и запасы) и переместите новое поле TemplateField так, чтобы оно располагалось над UnitPrice
BoundField.
Рис. 4. Добавление нового templateField в элемент управления DetailsView (щелкните для просмотра полноразмерного изображения)
Так как это новое templateField будет содержать значения, которые в настоящее время отображаются в UnitPrice
, UnitsInStock
и UnitsOnOrder
BoundFields, давайте удалим их.
Последняя задача на этом шаге — определить разметку ItemTemplate
для поля Price and Inventory TemplateField, которую можно выполнить либо с помощью интерфейса редактирования шаблона DetailsView в Designer, либо вручную с помощью декларативного синтаксиса элемента управления. Как и в случае с GridView, доступ к интерфейсу редактирования шаблона DetailsView можно получить, щелкнув ссылку Изменить шаблоны в смарт-теге. Здесь можно выбрать шаблон для редактирования из раскрывающегося списка, а затем добавить все веб-элементы управления из панели элементов.
Для работы с этим руководством начните с добавления элемента управления Метка в шаблон цены и инвентаризацииField ItemTemplate
. Затем щелкните ссылку Изменить DataBindings в смарт-теге элемента управления Label Web и привяжите Text
свойство к полю UnitPrice
.
Рис. 5. Привязка Text
свойства метки к полю UnitPrice
данных (щелкните для просмотра полноразмерного изображения)
Форматирование цены в виде валюты
С этим дополнением элемент управления "Цена и инвентаризация TemplateField" теперь отображает только цену на выбранный продукт. На рисунке 6 показан снимок экрана с нашими достижениями при просмотре в браузере.
Рис. 6. Шаблон цены и инвентаризацииВыполнение показывает цену (щелкните, чтобы просмотреть полноразмерное изображение)
Обратите внимание, что цена продукта не отформатирована как валюта. При использовании BoundField форматирование возможно путем задания свойству HtmlEncode
значения false
, а DataFormatString
свойства — значения {0:formatSpecifier}
. Однако для TemplateField все инструкции по форматированию должны быть указаны в синтаксисе привязки данных или с помощью метода форматирования, определенного в коде приложения (например, в классе кода программной части страницы ASP.NET).
Чтобы указать форматирование для синтаксиса привязки данных, используемого в элементе управления "Веб-метки", вернитесь в диалоговое окно DataBindings, щелкнув ссылку Edit DataBindings (Изменить привязки данных) из смарт-тега Label. Инструкции по форматированию можно ввести непосредственно в раскрывающемся списке Формат или выбрать одну из определенных строк формата. Как и в случае со свойством BoundField DataFormatString
, форматирование задается с помощью {0:formatSpecifier}
.
Для поля используйте UnitPrice
форматирование валюты, указанное путем выбора соответствующего значения раскрывающегося списка или путем ввода {0:C}
вручную.
Рис. 7. Форматирование цены в виде валюты (щелкните для просмотра полноразмерного изображения)
Декларативно спецификация форматирования указывается как второй параметр в методах Bind
или Eval
. Параметры, заданные с помощью Designer приводят к следующему выражению привязки данных в декларативной разметке:
<asp:Label ID="Label1" runat="server" Text='<%# Eval("UnitPrice", "{0:C}") %>'/>
Добавление оставшихся полей данных в TemplateField
На этом этапе мы отображали и форматировали UnitPrice
поле данных в поле Price and Inventory TemplateField, но по-прежнему UnitsInStock
необходимо отобразить поля и UnitsOnOrder
. Давайте отобразим их в строке под ценой и в скобках. В интерфейсе редактирования шаблона в Designer такую разметку можно добавить, разместив курсор в шаблоне и просто введя отображаемый текст. Кроме того, эту разметку можно ввести непосредственно в декларативном синтаксисе.
Добавьте статическую разметку, веб-элементы управления label и синтаксис привязки данных, чтобы в поле Price and Inventory TemplateField отображались сведения о ценах и запасах следующим образом:
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
, который принимает логическое значение в качестве входного параметра и возвращает строку. Как обсуждалось в предыдущем руководстве, этот метод должен быть помечен как protected
или public
, чтобы он был доступен из шаблона.
protected string DisplayDiscontinuedAsYESorNO(bool discontinued)
{
if (discontinued)
return "YES";
else
return "NO";
}
Этот метод проверяет входной параметр (discontinued
) и возвращает значение "YES", если оно равно true
, "НЕТ" в противном случае.
Примечание
В методе форматирования, рассмотренном в предыдущем руководстве, мы передавали поле данных, которое может содержать NULL
и, следовательно, необходимо проверка, если значение свойства сотрудника HiredDate
имеет значение базы данных NULL
перед доступом к EmployeesRow
свойству HiredDate
. Такой проверка здесь не требуется, так как столбцу Discontinued
никогда не могут быть назначены значения базы данныхNULL
. Более того, именно поэтому метод может принимать логический входной параметр вместо того, чтобы принимать ProductsRow
экземпляр или параметр типа object
.
После завершения этого метода форматирования остается только вызвать его из templateField ItemTemplate
. Чтобы создать TemplateField, удалите Discontinued
BoundField и добавьте новое templateField или преобразуйте Discontinued
BoundField в TemplateField. Затем в декларативном представлении разметки измените TemplateField так, чтобы оно содержало только ItemTemplate, которое вызывает DisplayDiscontinuedAsYESorNO
метод , передав значение свойства текущего ProductRow
экземпляра Discontinued
. Доступ к ней можно получить с помощью Eval
метода . В частности, разметка TemplateField должна выглядеть следующим образом:
<asp:TemplateField HeaderText="Discontinued" SortExpression="Discontinued">
<ItemTemplate>
<%# DisplayDiscontinuedAsYESorNO((bool)
Eval("Discontinued")) %>
</ItemTemplate>
</asp:TemplateField>
Это приведет к вызову DisplayDiscontinuedAsYESorNO
метода при отрисовке DetailsView, передавая ProductRow
значение экземпляра Discontinued
. Eval
Так как метод возвращает значение типа object
, но DisplayDiscontinuedAsYESorNO
метод ожидает входной параметр типа bool
, мы приведение возвращаемого Eval
значения методов к bool
. Затем DisplayDiscontinuedAsYESorNO
метод возвращает значение "YES" или "NO" в зависимости от получаемого значения. Возвращаемое значение — это то, что отображается в этой строке DetailsView (см. рис. 10).
Рис. 10. Значения "ДА" или "НЕТ" отображаются в строке "Неподдерживаемые" (щелкните для просмотра полноразмерного изображения)
Сводка
TemplateField в элементе управления DetailsView обеспечивает более высокую степень гибкости при отображении данных по сравнению с другими элементами управления полями, и идеально подходит для ситуаций, когда:
- В одном столбце GridView должно отображаться несколько полей данных
- Данные лучше всего выражаются с помощью веб-элемента управления, а не обычного текста
- Выходные данные зависят от базовых данных, таких как отображение метаданных или переформатирование данных
Хотя TemplateFields обеспечивают большую степень гибкости при отрисовке базовых данных DetailsView, выходные данные DetailsView по-прежнему считаются немного неровными, так как каждое поле отображается в виде строки в HTML <table>
.
Элемент управления FormView обеспечивает большую степень гибкости при настройке отображаемых выходных данных. FormView не содержит поля, а просто ряд шаблонов (ItemTemplate
, EditItemTemplate
, HeaderTemplate
и т. д.). В следующем руководстве мы рассмотрим, как использовать FormView для еще большего контроля над отображаемым макетом.
Счастливое программирование!
Об авторе
Скотт Митчелл (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.
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по