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


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

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

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

Те же возможности 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, и "НЕТ" в противном случае.

Для настройки отображения используются два templateFields

Рис. 1. Для настройки отображения используются два поля TemplateField (Щелкните для просмотра полноразмерного изображения)

Приступим к работе!

Шаг 1. Привязка данных к DetailsView

Как упоминалось в предыдущем руководстве, при работе с TemplateFields часто проще всего начать с создания элемента управления DetailsView, содержащего только BoundFields, а затем добавить новые TemplateFields или преобразовать существующие Поля BoundFields в TemplateFields при необходимости. Поэтому начните с этого руководства, добавив DetailsView на страницу через Designer и привязав его к ObjectDataSource, который возвращает список продуктов. Эти действия позволят создать DetailsView с BoundFields для каждого нелогического поля продукта и CheckBoxField для одного поля логического значения (Прекращено).

Откройте страницу DetailsViewTemplateField.aspx и перетащите DetailsView из панели элементов на Designer. В смарт-теге DetailsView выберите, чтобы добавить новый элемент управления ObjectDataSource, который вызывает ProductsBLL метод класса GetProducts() .

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

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

Для этого отчета удалите ProductID, SupplierID, CategoryIDи ReorderLevel BoundFields. Затем переупорядочение полей BoundFields так, чтобы CategoryName поля BoundField и SupplierName отображались сразу после 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) со строками, показывающими название продукта, категорию, поставщика, цену, единицы на складе, единицы заказа и его состояние прекращения.

Сведения о продукте отображаются с помощью ряда boundfields

Рис. 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.

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

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

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

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

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

Привязка текстового свойства метки к полю данных UnitPrice

Рис. 5. Привязка Text свойства метки к полю UnitPrice данных (щелкните для просмотра полноразмерного изображения)

Форматирование цены в виде валюты

С этим дополнением в элементе управления Цена и инвентаризация TemplateField веб-элемента управления Метка будет отображаться только цена на выбранный продукт. На рисунке 6 показан снимок экрана с нашими достижениями в браузере.

Шаблон цены и инвентаризацииВыполи показывает цену

Рис. 6. Шаблон цены и инвентаризацииВыполнение цены (щелкните для просмотра полноразмерного изображения)

Обратите внимание, что цена продукта не отформатирована в виде валюты. При использовании BoundField форматирование возможно путем задания свойству HtmlEncode значения False , а свойству DataFormatString — значение {0:formatSpecifier}. Однако для TemplateField все инструкции по форматированию должны быть указаны в синтаксисе привязки данных или с помощью метода форматирования, определенного в коде приложения (например, в классе кода программной части страницы ASP.NET).

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

Добавьте статическую разметку, веб-элементы управления метками и синтаксис привязки данных, чтобы в поле 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. Уделите немного времени, чтобы сделать это. После этого изменения в Представлении сведений отображается текст "True" для неподдерживаемых продуктов и "False" для продуктов, которые все еще активны.

Строки true и false используются для отображения состояния

Рис. 9. Строки True и False используются для отображения состояния прекращения (щелкните для просмотра полноразмерного изображения)

Представьте, что мы хотели использовать не строки True или False, а "ДА" и "НЕТ". Такая настройка может быть выполнена с помощью TemplateField и метода форматирования. Метод форматирования может принимать любое количество входных параметров, но должен возвращать HTML-код (в виде строки) для внедрения в шаблон.

Добавьте метод форматирования в DetailsViewTemplateField.aspx класс кода программной части страницы Northwind.ProductsRow с именем DisplayDiscontinuedAsYESorNO , который принимает объект в качестве входного параметра и возвращает строку. Как обсуждалось в предыдущем руководстве, этот метод должен быть помечен как 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 s, и поэтому необходимо проверка, если значение свойства сотрудника 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(Convert.ToBoolean(Eval("Discontinued")))%> 
    </ItemTemplate>
</asp:TemplateField>

Это приведет к вызову DisplayDiscontinuedAsYESorNO метода при отрисовке DetailsView, передавая ProductRow значение экземпляра Discontinued . Eval Так как метод возвращает значение типа Object, но DisplayDiscontinuedAsYESorNO метод ожидает входной параметр типа Boolean, мы приведение метода Eval возвращаемого значения к Boolean. Затем DisplayDiscontinuedAsYESorNO метод возвращает значения "ДА" или "НЕТ" в зависимости от получаемого значения. Возвращаемое значение — это то, что отображается в этой строке DetailsView (см. рис. 10).

Значения YES или NO теперь отображаются в строке

Рис. 10. Значения YES или NO теперь отображаются в строке "Прекращено" (щелкните для просмотра полноразмерного изображения)

Сводка

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.

Особая благодарность

Эта серия учебников была рассмотрена многими полезными рецензентами. Ведущим рецензентом этого руководства был Дэн Jagers. Хотите просмотреть предстоящие статьи MSDN? Если да, опустите мне строку на mitchell@4GuysFromRolla.com.