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


Использование TemplateField в элементе управления DetailsView (VB)

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

Скачать в формате PDF

Те же возможности 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 объединяет UnitPriceUnitsInStockполя данных и 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() .

Добавление нового элемента управления ObjectDataSource, вызывающего метод GetProducts()

Рис. 2. Добавление нового элемента управления ObjectDataSource, вызывающего GetProducts() метод (щелкните, чтобы просмотреть изображение полного размера)

Для этого отчета удалите ProductID, SupplierIDCategoryIDи 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) с строками с именем продукта, категорией, поставщиком, ценой, единицами в акции, единицами по заказу и его прекращенным состоянием.

Сведения о продукте показаны с помощью ряда boundFields

Рис. 3. Сведения о продукте показаны с помощью ряда BoundFields (щелкните для просмотра полного размера изображения)

Шаг 2. Объединение цен, единиц акций и единиц по заказу в одну строку

В DetailsView есть строка для UnitPriceUnitsInStockполей и UnitsOnOrder полей. Эти поля данных можно объединить в одну строку с TemplateField, добавив новый ШаблонФилд или преобразовав один из существующих UnitPriceполей и UnitsInStockUnitsOnOrder BoundFields в TemplateField. Хотя я лично предпочитаю преобразование существующих BoundFields, давайте добавим новый TemplateField.

Начните, щелкнув ссылку "Изменить поля" в смарт-теге DetailsView, чтобы открыть диалоговое окно "Поля". Затем добавьте новый templateField и задайте для его HeaderText свойства значение "Цена и инвентаризация" и переместите новый TemplateField, чтобы он был расположен над UnitPrice BoundField.

Добавление нового шаблона в элемент управления DetailsView

Рис. 4. Добавление нового templateField в элемент управления DetailsView (щелкните, чтобы просмотреть изображение полного размера)

Так как этот новый templateField будет содержать значения, отображаемые в настоящее время в UnitPriceUnitsInStockUnitsOnOrder BoundFields, давайте удалите их.

Последней задачей этого шага является определение ItemTemplate разметки для поля "Цена и инвентаризация", которое можно выполнить либо с помощью интерфейса редактирования шаблона DetailsView в конструкторе, либо с помощью декларативного синтаксиса элемента управления. Как и в GridView, доступ к интерфейсу редактирования шаблона DetailsView можно получить, щелкнув ссылку "Изменить шаблоны" в смарт-теге. Здесь вы можете выбрать шаблон для редактирования из раскрывающегося списка, а затем добавить все веб-элементы управления из панели элементов.

Для этого руководства начните с добавления элемента управления Label в шаблон ItemTemplate"Цена и инвентаризация". Затем щелкните ссылку "Изменить DataBindings" из смарт-тега веб-элемента управления Label и привязите Text свойство к UnitPrice полю.

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

Строки 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 перед доступом к EmployeesRowHiredDate свойству. Такая проверка не требуется, так как 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.