Использование TemplateField в элементе управления GridView (C#)Using TemplateFields in the GridView Control (C#)

по Скотт Митчеллby Scott Mitchell

Скачивание примера приложения или Загрузка PDF-файлаDownload Sample App or Download PDF

Для обеспечения гибкости GridView предлагает TemplateField, который готовится к просмотру с помощью шаблона.To provide flexibility, the GridView offers the TemplateField, which renders using a template. Шаблон может включать сочетание статического HTML, веб-элементов управления и синтаксиса привязки данных.A template can include a mix of static HTML, Web controls, and databinding syntax. В этом учебнике мы рассмотрим, как использовать TemplateField для достижения большей степени настройки с помощью элемента управления GridView.In this tutorial we'll examine how to use the TemplateField to achieve a greater degree of customization with the GridView control.

ВведениеIntroduction

GridView состоит из набора полей, указывающих, какие свойства из DataSource должны быть включены в отображаемые выходные данные вместе с тем, как будут отображаться данные.The GridView is composed of a set of fields that indicate what properties from the DataSource are to be included in the rendered output along with how the data will be displayed. Простейшим типом поля является BoundField, который отображает значение данных в виде текста.The simplest field type is the BoundField, which displays a data value as text. Другие типы полей отображают данные с помощью альтернативных HTML-элементов.Other field types display the data using alternate HTML elements. Например, CheckBoxField отображается в виде флажка, состояние которого зависит от значения указанного поля данных. Имажефиелд визуализирует изображение, источник изображения которого основан на указанном поле данных.The CheckBoxField, for example, renders as a checkbox whose checked state depends on the value of a specified data field; the ImageField renders an image whose image source is based upon a specified data field. Гиперссылки и кнопки, состояние которых зависит от значения базового поля данных, могут быть отображены с использованием типов полей HyperLinkField и Буттонфиелд.Hyperlinks and buttons whose state depends on an underlying data field value can be rendered using the HyperLinkField and ButtonField field types.

Хотя типы полей CheckBoxField, Имажефиелд, HyperLinkField и Буттонфиелд допускают альтернативное представление данных, они по-прежнему имеют достаточно ограничений относительно форматирования.While the CheckBoxField, ImageField, HyperLinkField, and ButtonField field types allow for an alternate view of the data, they still are fairly limited with respect to formatting. CheckBoxField может отображать только один флажок, в то время как Имажефиелд может отображать только одно изображение.A CheckBoxField can only display a single checkbox, whereas an ImageField can only display a single image. Что делать, если конкретному полю требуется отобразить некоторый текст, флажок и изображение, основанные на разных значениях полей данных?What if a particular field needs to display some text, a checkbox, and an image, all based upon different data field values? Или что делать, если нам нужно отобразить данные с помощью веб-элемента управления, отличного от флажка, изображения, гиперссылки или кнопки?Or what if we wanted to display the data using a Web control other than the CheckBox, Image, HyperLink, or Button? Кроме того, BoundField ограничивает его отображение одним полем данных.Furthermore, the BoundField limits its display to a single data field. Что делать, если нужно отобразить два или более значений полей данных в одном столбце GridView?What if we wanted to show two or more data field values in a single GridView column?

Чтобы обеспечить такой уровень гибкости, GridView предлагает TemplateField, который готовится к просмотру с помощью шаблона.To accommodate this level of flexibility the GridView offers the TemplateField, which renders using a template. Шаблон может включать сочетание статического HTML, веб-элементов управления и синтаксиса привязки данных.A template can include a mix of static HTML, Web controls, and databinding syntax. Более того, TemplateField имеет множество шаблонов, которые можно использовать для настройки отрисовки в различных ситуациях.Furthermore, the TemplateField has a variety of templates that can be used to customize the rendering for different situations. Например, ItemTemplate используется по умолчанию для отображения ячейки для каждой строки, но шаблон EditItemTemplate можно использовать для настройки интерфейса при редактировании данных.For example, the ItemTemplate is used by default to render the cell for each row, but the EditItemTemplate template can be used to customize the interface when editing data.

В этом учебнике мы рассмотрим, как использовать TemplateField для достижения большей степени настройки с помощью элемента управления GridView.In this tutorial we'll examine how to use the TemplateField to achieve a greater degree of customization with the GridView control. В предыдущем учебном курсе было показано, как настроить форматирование на основе базовых данных с помощью обработчиков событий DataBound и RowDataBound.In the preceding tutorial we saw how to customize the formatting based on the underlying data using the DataBound and RowDataBound event handlers. Другой способ настройки форматирования на основе базовых данных заключается в вызове методов форматирования из шаблона.Another way to customize the formatting based on the underlying data is by calling formatting methods from within a template. Мы также рассмотрим этот метод в этом учебнике.We'll look at this technique in this tutorial as well.

В этом учебнике мы будем использовать полей TemplateField для настройки внешнего вида списка сотрудников.For this tutorial we will use TemplateFields to customize the appearance of a list of employees. В частности, мы будем перечислять всех сотрудников, но в них будут отображаться имена и фамилии сотрудника в одном столбце, дата их найма в элементе управления Calendar, а также столбец состояния, показывающий, сколько дней они были использованы в компании.Specifically, we'll list all of the employees, but will display the employee's first and last names in one column, their hire date in a Calendar control, and a status column that indicates how many days they've been employed at the company.

для настройки экрана используются три полей TemplateFieldThree TemplateFields are Used to Customize the Display

Рис. 1. использование трех полей TemplateField для настройки отображения (щелкните, чтобы просмотреть изображение в полном размере)Figure 1: Three TemplateFields are Used to Customize the Display (Click to view full-size image)

Шаг 1. Привязка данных к GridViewStep 1: Binding the Data to the GridView

В сценариях создания отчетов, где необходимо использовать полей TemplateField для настройки внешнего вида, проще всего начать с создания элемента управления GridView, который содержит только BoundFields, а затем добавить новый полей TemplateField или преобразовать существующий BoundFields в При необходимости полей TemplateField.In reporting scenarios where you need to use TemplateFields to customize the appearance, I find it easiest to start by creating a GridView control that contains just BoundFields first and then to add new TemplateFields or convert the existing BoundFields to TemplateFields as needed. Поэтому начнем с этого руководства, добавив GridView на страницу в конструкторе и привязывая его к элементу ObjectDataSource, который возвращает список сотрудников.Therefore, let's start this tutorial by adding a GridView to the page through the Designer and binding it to an ObjectDataSource that returns the list of employees. В результате выполнения этих действий будет создан элемент управления GridView с BoundFields для каждого поля сотрудника.These steps will create a GridView with BoundFields for each of the employee fields.

Откройте страницу GridViewTemplateField.aspx и перетащите элемент GridView с панели инструментов в конструктор.Open the GridViewTemplateField.aspx page and drag a GridView from the Toolbox onto the Designer. В смарт-теге GridView выберите Добавление нового элемента управления ObjectDataSource, который вызывает метод GetEmployees() класса EmployeesBLL.From the GridView's smart tag choose to add a new ObjectDataSource control that invokes the EmployeesBLL class's GetEmployees() method.

добавить новый элемент управления ObjectDataSource, вызывающий метод «сотрудники ()»Add a New ObjectDataSource Control that Invokes the GetEmployees() Method

Рис. 2. Добавление нового элемента управления ObjectDataSource, который вызывает метод GetEmployees() (щелкните, чтобы просмотреть изображение с полным размером)Figure 2: Add a New ObjectDataSource Control that Invokes the GetEmployees() Method (Click to view full-size image)

Таким образом привязка GridView будет автоматически добавлять BoundField для каждого свойства сотрудника: EmployeeID, LastName, FirstName, Title, HireDate, ReportsToи Country.Binding the GridView in this manner will automatically add a BoundField for each of the employee properties: EmployeeID, LastName, FirstName, Title, HireDate, ReportsTo, and Country. Для этого отчета не стоит тратиться на отображение свойств EmployeeID, ReportsToили Country.For this report let's not bother with displaying the EmployeeID, ReportsTo, or Country properties. Чтобы удалить эти BoundFields, можно выполнить следующие действия.To remove these BoundFields you can:

  • Используйте диалоговое окно поля. чтобы открыть это диалоговое окно, щелкните ссылку изменить столбцы в смарт-теге GridView.Use the Fields dialog box click on the Edit Columns link from the GridView's smart tag to bring up this dialog box. Затем выберите BoundFields из левого нижнего списка и нажмите красную кнопку X, чтобы удалить BoundField.Next, select the BoundFields from the lower left list and click the red X button to remove the BoundField.
  • Измените декларативный синтаксис GridView вручную из представления исходного кода, удалив элемент <asp:BoundField> для BoundField, который необходимо удалить.Edit the GridView's declarative syntax by hand from the Source view, delete the <asp:BoundField> element for the BoundField you wish to remove.

После удаления EmployeeID, ReportsToи Country BoundFields разметка GridView должна выглядеть следующим образом:After you have removed the EmployeeID, ReportsTo, and Country BoundFields, your GridView's markup should look like:

<asp:GridView ID="GridView1" runat="server"
    AutoGenerateColumns="False" DataKeyNames="EmployeeID"
    DataSourceID="ObjectDataSource1">
    <Columns>
        <asp:BoundField DataField="LastName" HeaderText="LastName"
            SortExpression="LastName" />
        <asp:BoundField DataField="FirstName" HeaderText="FirstName"
            SortExpression="FirstName" />
        <asp:BoundField DataField="Title" HeaderText="Title"
            SortExpression="Title" />
        <asp:BoundField DataField="HireDate" HeaderText="HireDate"
            SortExpression="HireDate" />
    </Columns>
</asp:GridView>

Уделите время для просмотра хода выполнения в браузере.Take a moment to view our progress in a browser. На этом этапе вы увидите таблицу с записью для каждого сотрудника и четырьмя столбцами: один для фамилии сотрудника, один для своего имени, один для своего названия, а другой — для их даты найма.At this point you should see a table with a record for each employee and four columns: one for the employee's last name, one for their first name, one for their title, and one for their hire date.

поля LastName, FirstName, Title и HireDate отображаются для каждого сотрудника.The LastName, FirstName, Title, and HireDate Fields are Displayed for Each Employee

Рис. 3. поля LastName, FirstName, Titleи HireDate отображаются для каждого сотрудника (щелкните, чтобы просмотреть изображение с полным размером).Figure 3: The LastName, FirstName, Title, and HireDate Fields are Displayed for Each Employee (Click to view full-size image)

Шаг 2. Отображение первого и последнего имен в одном столбцеStep 2: Displaying the First and Last Names in a Single Column

В настоящее время имя и фамилия каждого сотрудника отображаются в отдельном столбце.Currently, each employee's first and last names are displayed in a separate column. Вместо этого может быть приятно объединить их в один столбец.It might be nice to combine them into a single column instead. Для этого необходимо использовать TemplateField.To accomplish this we need to use a TemplateField. Мы можем добавить новый TemplateField, добавить к нему требуемую разметку и синтаксис привязки данных, а затем удалить FirstName и LastName BoundFields или преобразовать FirstName BoundField в TemplateField, изменить TemplateField, включив LastName значение, а затем удалить LastName BoundField.We can either add a new TemplateField, add to it the needed markup and databinding syntax, and then delete the FirstName and LastName BoundFields, or we can convert the FirstName BoundField into a TemplateField, edit the TemplateField to include the LastName value, and then remove the LastName BoundField.

Оба подхода имеют одинаковый результат, но лично я предпочитаю преобразовывать BoundFields в полей TemplateField, когда это возможно, так как преобразование автоматически добавляет ItemTemplate и EditItemTemplate с веб-элементами управления и синтаксис привязки данных для имитации внешнего вида и функциональности BoundField.Both approaches net the same result, but personally I like converting BoundFields to TemplateFields when possible because the conversion automatically adds an ItemTemplate and EditItemTemplate with Web controls and databinding syntax to mimic the appearance and functionality of the BoundField. Преимущество заключается в том, что нам потребуется меньше работы с TemplateField, так как в процессе преобразования будет выполнена часть работы для нас.The benefit is that we'll need to do less work with the TemplateField as the conversion process will have performed some of the work for us.

Чтобы преобразовать существующий BoundField в TemplateField, щелкните ссылку Edit Columns (изменить столбцы) в смарт-теге GridView и откройте диалоговое окно "поля".To convert an existing BoundField into a TemplateField, click on the Edit Columns link from the GridView's smart tag, bringing up the Fields dialog box. Выберите BoundField для преобразования из списка в левом нижнем углу и щелкните ссылку "преобразовать это поле в TemplateField" в правом нижнем углу.Select the BoundField to convert from the list in the lower left corner and then click the "Convert this field into a TemplateField" link in the bottom right corner.

преобразование BoundField в TemplateField из диалогового окна "поля"Convert a BoundField Into a TemplateField from the Fields Dialog Box

Рис. 4. Преобразование BoundField в TemplateField из диалогового окна "поля" (щелкните, чтобы просмотреть изображение с полным размером)Figure 4: Convert a BoundField Into a TemplateField from the Fields Dialog Box (Click to view full-size image)

Преобразуйте FirstName BoundField в TemplateField.Go ahead and convert the FirstName BoundField into a TemplateField. После этого изменения в конструкторе нет перцептиве разницы.After this change there's no perceptive difference in the Designer. Это обусловлено тем, что преобразование BoundField в TemplateField создает TemplateField, который поддерживает внешний вид и поведение BoundField.This is because converting the BoundField into a TemplateField creates a TemplateField that maintains the look and feel of the BoundField. Несмотря на то, что на этом этапе конструктора нет визуальной разницы, этот процесс преобразования заменил декларативный синтаксис BoundField-<asp:BoundField DataField="FirstName" HeaderText="FirstName" SortExpression="FirstName" /> на следующий синтаксис TemplateField:Despite there being no visual difference at this point in the Designer, this conversion process has replaced the BoundField's declarative syntax - <asp:BoundField DataField="FirstName" HeaderText="FirstName" SortExpression="FirstName" /> - with the following TemplateField syntax:

<asp:TemplateField HeaderText="FirstName" SortExpression="FirstName">
    <EditItemTemplate>
        <asp:TextBox ID="TextBox1" runat="server"
            Text='<%# Bind("FirstName") %>'></asp:TextBox>
    </EditItemTemplate>
    <ItemTemplate>
        <asp:Label ID="Label1" runat="server"
            Text='<%# Bind("FirstName") %>'></asp:Label>
    </ItemTemplate>
</asp:TemplateField>

Как видите, TemplateField состоит из двух шаблонов: ItemTemplate с меткой, Text свойству которой присвоено значение поля данных FirstName, а EditItemTemplate с элементом управления TextBox, свойство Text которого также установлено в поле данных FirstName.As you can see, the TemplateField consists of two templates an ItemTemplate that has a Label whose Text property is set to the value of the FirstName data field, and an EditItemTemplate with a TextBox control whose Text property is also set to the FirstName data field. Синтаксис DataBinding — <%# Bind("fieldName") %> — указывает, что поле данных fieldName привязано к указанному свойству веб-элемента управления.The databinding syntax - <%# Bind("fieldName") %> - indicates that the data field fieldName is bound to the specified Web control property.

Чтобы добавить значение поля данных LastName в эту TemplateField, необходимо добавить еще один веб-элемент управления Label в ItemTemplate и привязать его свойство Text к LastName.To add the LastName data field value to this TemplateField we need to add another Label Web control in the ItemTemplate and bind its Text property to LastName. Это можно сделать либо вручную, либо с помощью конструктора.This can be accomplished either by hand or through the Designer. Чтобы сделать это вручную, просто добавьте соответствующий декларативный синтаксис в ItemTemplate:To do it by hand, simply add the appropriate declarative syntax to the ItemTemplate:

<asp:TemplateField HeaderText="FirstName" SortExpression="FirstName">
    <EditItemTemplate>
        <asp:TextBox ID="TextBox1" runat="server"
            Text='<%# Bind("FirstName") %>'></asp:TextBox>
    </EditItemTemplate>
    <ItemTemplate>
        <asp:Label ID="Label1" runat="server"
            Text='<%# Bind("FirstName") %>'></asp:Label>
        <asp:Label ID="Label2" runat="server"
            Text='<%# Bind("LastName") %>'></asp:Label>
    </ItemTemplate>
</asp:TemplateField>

Чтобы добавить его через конструктор, щелкните ссылку Edit Templates (изменить шаблоны) в смарт-теге GridView.To add it through the Designer, click on the Edit Templates link from the GridView's smart tag. Будет отображен интерфейс редактирования шаблона GridView.This will display the GridView's template editing interface. В смарт-теге этого интерфейса есть список шаблонов в GridView.In this interface's smart tag is a list of the templates in the GridView. Так как у нас есть только одна TemplateField на этом этапе, единственными шаблонами, перечисленными в раскрывающемся списке, являются шаблоны для FirstName TemplateField, а также EmptyDataTemplate и PagerTemplate.Since we only have one TemplateField at this point, the only templates listed in the drop-down list are those templates for the FirstName TemplateField along with the EmptyDataTemplate and PagerTemplate. Шаблон EmptyDataTemplate, если он указан, используется для отображения выходных данных GridView, если нет результатов, привязанных к GridView; PagerTemplate, если он указан, используется для отрисовки интерфейса разбиения по страницам для GridView, поддерживающего разбиение на страницы.The EmptyDataTemplate template, if specified, is used to render the GridView's output if there are no results in the data bound to the GridView; the PagerTemplate, if specified, is used to render the paging interface for a GridView that supports paging.

шаблоны GridView можно редактировать с помощью конструктораThe GridView's Templates Can Be Edited Through the Designer

Рис. 5. шаблоны GridView можно изменять с помощью конструктора (щелкните, чтобы просмотреть изображение с полным размером)Figure 5: The GridView's Templates Can Be Edited Through the Designer (Click to view full-size image)

Чтобы также отобразить LastName в FirstName TemplateField перетащите элемент управления Label с панели элементов в ItemTemplate FirstName TemplateField в интерфейсе редактирования шаблона GridView.To also display the LastName in the FirstName TemplateField drag the Label control from the Toolbox into the FirstName TemplateField's ItemTemplate in the GridView's template editing interface.

добавить веб-элемент управления Label к ItemTemplate элемента FirstName TemplateFieldAdd a Label Web Control to the FirstName TemplateField's ItemTemplate

Рис. 6. Добавление элемента управления Label к элементу ItemTemplate FirstName TemplateField (щелкните, чтобы просмотреть изображение с полным размером)Figure 6: Add a Label Web Control to the FirstName TemplateField's ItemTemplate (Click to view full-size image)

На этом этапе для веб-элемента управления Label, добавленного в TemplateField, свойство Text имеет значение "Label".At this point the Label Web control added to the TemplateField has its Text property set to "Label". Необходимо изменить это значение, чтобы это свойство было привязано к значению LastName поля данных.We need to change this so that this property is bound to the value of the LastName data field instead. Чтобы сделать это, щелкните смарт-тег элемента управления Label и выберите параметр изменить привязки к данным.To accomplish this click on the Label control's smart tag and choose the Edit DataBindings option.

выберите параметр изменить DataBindings в смарт-теге метки.Choose the Edit DataBindings Option from the Label's Smart Tag

Рис. 7. Выбор параметра изменить DataBindings в смарт-теге метки (щелкните, чтобы просмотреть изображение с полным размером)Figure 7: Choose the Edit DataBindings Option from the Label's Smart Tag (Click to view full-size image)

Откроется диалоговое окно привязки к данным.This will bring up the DataBindings dialog box. Здесь можно выбрать свойство для участия в DataBinding из списка слева и выбрать поле для привязки данных из раскрывающегося списка справа.From here you can select the property to participate in databinding from the list on the left and choose the field to bind the data to from the drop-down list on the right. Выберите свойство Text слева и поле LastName справа и нажмите кнопку ОК.Choose the Text property from the left and the LastName field from the right and click OK.

привязать свойство Text к полю данных LastNameBind the Text Property to the LastName Data Field

Рис. 8. привязка свойства Text к полю данных LastName (щелкните, чтобы просмотреть изображение с полным размером)Figure 8: Bind the Text Property to the LastName Data Field (Click to view full-size image)

Note

Диалоговое окно DataBindings позволяет указать, следует ли выполнять двустороннюю привязку данных.The DataBindings dialog box allows you to indicate whether to perform two-way databinding. Если оставить этот флажок снятым, вместо <%# Bind("LastName")%>будет использоваться синтаксис привязки данных <%# Eval("LastName")%>.If you leave this unchecked, the databinding syntax <%# Eval("LastName")%> will be used instead of <%# Bind("LastName")%>. Для работы с этим руководством подходит любой из этих подходов.Either approach is fine for this tutorial. Двусторонняя привязка при вставке и изменении данных играет важную роль.Two-way databinding becomes important when inserting and editing data. Однако для простого отображения данных любой из этих подходов будет работать одинаково хорошо.For simply displaying data, however, either approach will work equally well. В следующих учебных курсах мы подробно рассмотрим двустороннюю привязку данных.We'll discuss two-way databinding in detail in future tutorials.

Уделите несколько минут для просмотра этой страницы в браузере.Take a moment to view this page through a browser. Как видите, GridView по-прежнему включает четыре столбца. Однако столбец FirstName теперь содержит FirstName и LastName значения полей данных.As you can see, the GridView still includes four columns; however, the FirstName column now lists both the FirstName and LastName data field values.

оба значения FirstName и LastName показаны в одном столбцеBoth the FirstName and LastName Values are Shown in a Single Column

Рис. 9. значения FirstName и LastName показаны в одном столбце (щелкните, чтобы просмотреть изображение с полным размером).Figure 9: Both the FirstName and LastName Values are Shown in a Single Column (Click to view full-size image)

Чтобы выполнить первый шаг, удалите LastName BoundField и переименуйте свойство FirstName TemplateField HeaderText в "Name".To complete this first step, remove the LastName BoundField and rename the FirstName TemplateField's HeaderText property to "Name". После этих изменений декларативная разметка GridView должна выглядеть следующим образом:After these changes the GridView's declarative markup should look like the following:

<asp:GridView ID="GridView1" runat="server"
    AutoGenerateColumns="False" DataKeyNames="EmployeeID"
    DataSourceID="ObjectDataSource1">
    <Columns>
        <asp:TemplateField HeaderText="Name" SortExpression="FirstName">
            <EditItemTemplate>
                <asp:TextBox ID="TextBox1" runat="server"
                    Text='<%# Bind("FirstName") %>'></asp:TextBox>
            </EditItemTemplate>
            <ItemTemplate>
                <asp:Label ID="Label1" runat="server"
                    Text='<%# Bind("FirstName") %>'></asp:Label>
                <asp:Label ID="Label2" runat="server"
                    Text='<%# Eval("LastName") %>'></asp:Label>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:BoundField DataField="Title" HeaderText="Title"
            SortExpression="Title" />
        <asp:BoundField DataField="HireDate" HeaderText="HireDate"
            SortExpression="HireDate" />
    </Columns>
</asp:GridView>

имя и фамилии каждого сотрудника отображаются в одном столбцеEach Employee's First and Last Names are Displayed in One Column

Рис. 10. имя и фамилия каждого сотрудника отображаются в одном столбце (щелкните, чтобы просмотреть изображение с полным размером)Figure 10: Each Employee's First and Last Names are Displayed in One Column (Click to view full-size image)

Шаг 3. Использование элемента управления Calendar для вывода поляHiredDateStep 3: Using the Calendar Control to Display theHiredDateField

Отображение значения поля данных в виде текста в элементе управления GridView осуществляется так же просто, как использование BoundField.Displaying a data field value as text in a GridView is as simple as using a BoundField. Однако в некоторых сценариях данные лучше всего выражаются с помощью определенного веб-элемента управления, а не только текста.For certain scenarios, however, the data is best expressed using a particular Web control instead of just text. Такая настройка представления данных возможна при использовании полей TemplateField.Such customization of the display of data is possible with TemplateFields. Например, вместо отображения даты найма сотрудника в виде текста можно отобразить календарь (с помощью элемента управления Calendar) с выделенной датой найма.For example, rather than display the employee's hire date as text, we could show a calendar (using the Calendar control) with their hire date highlighted.

Чтобы добиться этого, начните с преобразования HiredDate BoundField в TemplateField.To accomplish this, start by converting the HiredDate BoundField into a TemplateField. Просто перейдите к смарт-тегу GridView и щелкните ссылку изменить столбцы, чтобы открыть диалоговое окно поля.Simply go to the GridView's smart tag and click the Edit Columns link, bringing up the Fields dialog box. Выберите HiredDate BoundField и щелкните "преобразовать это поле в TemplateField".Select the HiredDate BoundField and click "Convert this field into a TemplateField."

преобразовать BoundField Хиреддате в TemplateFieldConvert the HiredDate BoundField Into a TemplateField

Рис. 11. Преобразование HiredDate BoundField в TemplateField (щелкните, чтобы просмотреть изображение с полным размером)Figure 11: Convert the HiredDate BoundField Into a TemplateField (Click to view full-size image)

Как было показано на шаге 2, это приведет к замене BoundField на TemplateField, содержащий ItemTemplate и EditItemTemplate с меткой и TextBox, свойства Text которых привязаны к значению HiredDate с помощью синтаксиса DataBinding <%# Bind("HiredDate")%>.As we saw in Step 2, this will replace the BoundField with a TemplateField that contains an ItemTemplate and EditItemTemplate with a Label and TextBox whose Text properties are bound to the HiredDate value using the databinding syntax <%# Bind("HiredDate")%>.

Чтобы заменить текст элементом управления "Календарь", измените шаблон, удалив метку и добавив элемент управления "Календарь".To replace the text with a Calendar control, edit the template by removing the Label and adding a Calendar control. В конструкторе выберите изменить шаблоны из смарт-тега GridView и выберите ItemTemplate HireDate TemplateField из раскрывающегося списка.From the Designer, select Edit Templates from the GridView's smart tag and choose the HireDate TemplateField's ItemTemplate from the drop-down list. Затем удалите элемент управления Label и перетащите элемент управления Calendar из панели элементов в интерфейс редактирования шаблона.Next, delete the Label control and drag a Calendar control from the Toolbox into the template editing interface.

добавить элемент управления Calendar в столбец ItemTemplate TemplateFieldAdd a Calendar Control to the HireDate TemplateField's ItemTemplate

Рис. 12. Добавление элемента управления Calendar в ItemTemplate HireDate TemplateField (щелкните, чтобы просмотреть изображение с полным размером)Figure 12: Add a Calendar Control to the HireDate TemplateField's ItemTemplate (Click to view full-size image)

На этом этапе каждая строка в GridView будет содержать элемент управления Calendar в своем HiredDate TemplateField.At this point each row in the GridView will contain a Calendar control in its HiredDate TemplateField. Однако фактическое значение HiredDate сотрудника не задается в любом месте элемента управления Calendar, в результате чего каждый элемент управления Calendar по умолчанию отображает текущий месяц и дату.However, the employee's actual HiredDate value is not set anywhere in the Calendar control, causing each Calendar control to default to showing the current month and date. Чтобы устранить эту проблему, необходимо назначить HiredDate каждого сотрудника свойствам SelectedDate и Висибледате элемента управления Calendar.To remedy this, we need to assign each employee's HiredDate to the Calendar control's SelectedDate and VisibleDate properties.

В смарт-теге элемента управления Calendar выберите Edit Databindingss.From the Calendar control's smart tag, choose Edit DataBindings. Затем привяжите свойства SelectedDate и VisibleDate к полю данных HiredDate.Next, bind both SelectedDate and VisibleDate properties to the HiredDate data field.

привязать свойства SelectedDate и Висибледате к полю данных ХиреддатеBind the SelectedDate and VisibleDate Properties to the HiredDate Data Field

Рис. 13. привязка свойств SelectedDate и VisibleDate к полю данных HiredDate (щелкните, чтобы просмотреть изображение с полным размером)Figure 13: Bind the SelectedDate and VisibleDate Properties to the HiredDate Data Field (Click to view full-size image)

Note

Выбранную дату элемента управления календаря не обязательно должны быть видимыми.The Calendar control's selected date need not necessarily be visible. Например, в календаре может быть 1 августа 1999 в качестве выбраннойдаты, ноотображается текущий месяц и год.For example, a Calendar may have August 1st, 1999 as the selected date, but be showing the current month and year. Выбранная дата и видимая Дата задаются свойствами SelectedDate и VisibleDate элемента управления Calendar.The selected date and visible date are specified by the Calendar control's SelectedDate and VisibleDate properties. Так как мы хотим выбрать HiredDate сотрудника и убедиться, что он показан, необходимо привязать оба свойства к полю данных HireDate.Since we want to both select the employee's HiredDate and make sure that it's shown we need to bind both of these properties to the HireDate data field.

При просмотре страницы в браузере календарь теперь показывает месяц срока найма сотрудника и выбирает эту конкретную дату.When viewing the page in a browser, the calendar now shows the month of the employee's hired date and selects that particular date.

Хиреддате сотрудника отображается в элементе управления CalendarThe Employee's HiredDate is Shown in the Calendar Control

Рис. 14. HiredDate сотрудника отображается в элементе управления Calendar (щелкните, чтобы просмотреть изображение с полным размером)Figure 14: The Employee's HiredDate is Shown in the Calendar Control (Click to view full-size image)

Note

В отличие от всех примеров, которые мы видели до сих пор, в этом учебнике не было задано свойство EnableViewState для false для этого элемента управления GridView.Contrary to all the examples we've seen thus far, for this tutorial we did not set EnableViewState property to false for this GridView. Причина этого решения заключается в том, что щелчок дат элемента управления Calendar вызывает обратную передачу, устанавливая выбранную дату календаря в только что нажатую дату.The reason for this decision is because clicking the dates of the Calendar control causes a postback, setting the Calendar's selected date to the date just clicked. Однако если состояние представления GridView отключено, при каждой обратной передаче данные GridView повторно привязаны к базовому источнику данных, что приводит к тому, что выбранная дата календаря возвращается в HireDateсотрудника, перезаписывая дату, выбранную пользователем.If the GridView's view state is disabled, however, on each postback the GridView's data is rebound to its underlying data source, which causes the Calendar's selected date to be set back to the employee's HireDate, overwriting the date chosen by the user.

В этом учебнике это затеи обсуждение, так как пользователь не может обновить HireDateсотрудника.For this tutorial this is a moot discussion since the user is not able to update the employee's HireDate. Вероятно, лучше настроить элемент управления Calendar так, чтобы его даты не выглядели как выбираемые.It would probably be best to configure the Calendar control so that its dates are not selectable. Независимо от этого учебник показывает, что в некоторых обстоятельствах состояние представления должно быть включено, чтобы обеспечить определенные функциональные возможности.Regardless, this tutorial shows that in some circumstances view state must be enabled in order to provide certain functionality.

Шаг 4. Отображение количества дней, в течение которых сотрудник работал в компанииStep 4: Showing the Number of Days the Employee Has Worked for the Company

Пока мы видели два приложения полей TemplateField:So far we have seen two applications of TemplateFields:

  • Объединение двух или более значений полей данных в один столбец;Combining two or more data field values into one column, and
  • Выражение значения поля данных с помощью веб-элемента управления, а не текстаExpressing a data field value using a Web control instead of text

Третье использование полей TemplateField — отображение метаданных о базовых данных GridView.A third use of TemplateFields is in displaying metadata about the GridView's underlying data. В дополнение к отображению дат найма сотрудников, например, нам может потребоваться столбец, в котором отображается общее количество дней, в течение которых они были заданы.In addition to showing the employees' hire dates, for example, we might also want to have a column that displays how many total days they've been on the job.

Еще одно использование полей TemplateField возникает в сценариях, когда базовые данные должны отображаться иначе в отчете веб-страницы, чем в формате, хранящемся в базе данных.Yet another use of TemplateFields arises in scenarios when the underlying data needs to be displayed differently in the web page report than in the format it's stored in the database. Предположим, что в Employees таблице имелось Gender поле, в котором хранится знак M или F для обозначения пол сотрудника.Imagine that the Employees table had a Gender field that stored the character M or F to indicate the sex of the employee. При отображении этих сведений на веб-странице может потребоваться отобразить пол или женщина, а не просто "M" или "F".When displaying this information in a web page we might want to show the gender as either "Male" or "Female", as opposed to just "M" or "F".

Оба этих сценария можно обработать, создав метод форматирования в классе кода программной части страницы ASP.NET (или в отдельной библиотеке классов, реализованном как метод static), который вызывается из шаблона.Both of these scenarios can be handled by creating a formatting method in the ASP.NET page's code-behind class (or in a separate class library, implemented as a static method) that is invoked from the template. Такой метод форматирования вызывается из шаблона с использованием того же синтаксиса DataBinding, который рассматривался ранее.Such a formatting method is invoked from the template using the same databinding syntax seen earlier. Метод форматирования может принимать любое количество параметров, но должен возвращать строку.The formatting method can take in any number of parameters, but must return a string. Возвращаемая строка — это код HTML, который внедряется в шаблон.This returned string is the HTML that is injected into the template.

Чтобы проиллюстрировать эту концепцию, давайте добавим наш учебник, чтобы показать столбец со списком общего количества дней, в течение которых сотрудник находится в задании.To illustrate this concept, let's augment our tutorial to show a column that lists the total number of days an employee has been on the job. Этот метод форматирования будет принимать объект Northwind.EmployeesRow и возвращать количество дней, в течение которых сотрудник работал в виде строки.This formatting method will take in a Northwind.EmployeesRow object and return the number of days the employee has been employed as a string. Этот метод может быть добавлен к классу кода программной части страницы ASP.NET, но должен быть помечен как protected или public, чтобы быть доступен из шаблона.This method can be added to the ASP.NET page's code-behind class, but must be marked as protected or public in order to be accessible from the template.

protected string DisplayDaysOnJob(Northwind.EmployeesRow employee)
{
    // Make sure HiredDate is not null... if so, return "Unknown"
    if (employee.IsHireDateNull())
        return "Unknown";
    else
    {
        // Returns the number of days between the current
        // date/time and HireDate
        TimeSpan ts = DateTime.Now.Subtract(employee.HireDate);
        return ts.Days.ToString("#,##0");
    }
}

Так как поле HiredDate может содержать NULL значения базы данных, перед продолжением вычисления необходимо убедиться, что это значение не NULL.Since the HiredDate field can contain NULL database values we must first ensure that the value is not NULL before proceeding with the calculation. Если HiredDate значение равно NULL, мы просто возвращаем строку "Unknown". Если это не NULL, мы вычислим разницу между текущим временем и значением HiredDate и возвращающим количество дней.If the HiredDate value is NULL, we simply return the string "Unknown"; if it is not NULL, we compute the difference between the current time and the HiredDate value and return the number of days.

Чтобы использовать этот метод, необходимо вызвать его из TemplateField в GridView с помощью синтаксиса DataBinding.To utilize this method we need to invoke it from a TemplateField in the GridView using the databinding syntax. Начните с добавления нового TemplateField в GridView, щелкнув ссылку Edit Columns (изменить столбцы) в смарт-теге GridView и добавив новый TemplateField.Start by adding a new TemplateField to the GridView by clicking on the Edit Columns link in the GridView's smart tag and adding a new TemplateField.

добавить новый TemplateField в GridViewAdd a New TemplateField to the GridView

Рис. 15. Добавление нового TemplateField в GridView (щелкните, чтобы просмотреть изображение с полным размером)Figure 15: Add a New TemplateField to the GridView (Click to view full-size image)

Задайте для свойства HeaderText нового TemplateField значение "дни в задании", а для свойства HorizontalAlign его ItemStyleзначение Center.Set this new TemplateField's HeaderText property to "Days on the Job" and its ItemStyle's HorizontalAlign property to Center. Чтобы вызвать метод DisplayDaysOnJob из шаблона, добавьте ItemTemplate и используйте следующий синтаксис привязки данных:To call the DisplayDaysOnJob method from the template, add an ItemTemplate and use the following databinding syntax:

<%# DisplayDaysOnJob((Northwind.EmployeesRow)
     ((System.Data.DataRowView) Container.DataItem).Row) %>

Container.DataItem возвращает объект DataRowView, соответствующий записи DataSource, привязанной к GridViewRow.Container.DataItem returns a DataRowView object corresponding to the DataSource record bound to the GridViewRow. Свойство Row возвращает строго типизированный Northwind.EmployeesRow, который передается в метод DisplayDaysOnJob.Its Row property returns the strongly-typed Northwind.EmployeesRow, which is passed to the DisplayDaysOnJob method. Синтаксис DataBinding может отображаться непосредственно в ItemTemplate (как показано в декларативном синтаксисе ниже) или может быть назначен свойству Text веб-элемента управления Label.This databinding syntax can appear directly in the ItemTemplate (as shown in the declarative syntax below) or can be assigned to the Text property of a Label Web control.

Note

Кроме того, вместо передачи экземпляра EmployeesRow можно просто передать значение HireDate с помощью <%# DisplayDaysOnJob(Eval("HireDate")) %>.Alternatively, instead of passing in an EmployeesRow instance, we could just pass in the HireDate value using <%# DisplayDaysOnJob(Eval("HireDate")) %>. Однако метод Eval возвращает object, поэтому нам пришлось бы изменить сигнатуру метода DisplayDaysOnJob, чтобы вместо нее принимался входной параметр типа object.However, the Eval method returns an object, so we'd have to change our DisplayDaysOnJob method signature to accept an input parameter of type object, instead. Невозможно выполнить неявное приведение Eval("HireDate") вызова к DateTime, так как столбец HireDate в таблице Employees может содержать NULL значения.We can't blindly cast the Eval("HireDate") call to a DateTime because the HireDate column in the Employees table can contain NULL values. Поэтому нам нужно принять object в качестве входного параметра для метода DisplayDaysOnJob, проверить, имел ли он значение NULL базы данных (которое можно выполнить с помощью Convert.IsDBNull(objectToCheck)), и затем выполнить соответствующее выполнение.Therefore, we'd need to accept an object as the input parameter for the DisplayDaysOnJob method, check to see if it had a database NULL value (which can be accomplished using Convert.IsDBNull(objectToCheck)), and then proceed accordingly.

Из-за этих тонкостей я решил передать весь экземпляр EmployeesRow.Due to these subtleties, I've opted to pass in the entire EmployeesRow instance. В следующем учебном курсе будет представлен более подходящий пример использования синтаксиса Eval("columnName") для передачи входного параметра в метод форматирования.In the next tutorial we'll see a more fitting example for using the Eval("columnName") syntax for passing an input parameter into a formatting method.

Ниже показан декларативный синтаксис для нашего GridView после добавления TemplateField и метод DisplayDaysOnJob, вызываемый из ItemTemplate:The following shows the declarative syntax for our GridView after the TemplateField has been added and the DisplayDaysOnJob method called from the ItemTemplate:

<asp:GridView ID="GridView1" runat="server"
    AutoGenerateColumns="False" DataKeyNames="EmployeeID"
    DataSourceID="ObjectDataSource1">
    <Columns>
        <asp:TemplateField HeaderText="Name" SortExpression="FirstName">
            <EditItemTemplate>
                <asp:TextBox ID="TextBox1" runat="server"
                    Text='<%# Bind("FirstName") %>'></asp:TextBox>
            </EditItemTemplate>
            <ItemTemplate>
                <asp:Label ID="Label1" runat="server"
                    Text='<%# Bind("FirstName") %>'></asp:Label>
                <asp:Label ID="Label2" runat="server"
                    Text='<%# Eval("LastName") %>'></asp:Label>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:BoundField DataField="Title" HeaderText="Title"
            SortExpression="Title" />
        <asp:TemplateField HeaderText="HireDate"
            SortExpression="HireDate">
            <EditItemTemplate>
                <asp:TextBox ID="TextBox2" runat="server"
                    Text='<%# Bind("HireDate") %>'></asp:TextBox>
            </EditItemTemplate>
            <ItemTemplate>
                <asp:Calendar ID="Calendar1" runat="server"
                    SelectedDate='<%# Bind("HireDate") %>'
                    VisibleDate='<%# Eval("HireDate") %>'>
            </asp:Calendar>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Days On The Job">
            <ItemTemplate>
                <%# DisplayDaysOnJob((Northwind.EmployeesRow)
                    ((System.Data.DataRowView) Container.DataItem).Row) %>
            </ItemTemplate>
            <ItemStyle HorizontalAlign="Center" />
        </asp:TemplateField>
    </Columns>
</asp:GridView>

На рис. 16 показан завершенный учебник при просмотре в браузере.Figure 16 shows the completed tutorial, when viewed through a browser.

число дней, на которое отображается сотрудник в заданииThe Number of Days the Employee Has Been on the Job is Displayed

Рис. 16. число дней, в течение которых сотрудник находится в задании (щелкните, чтобы просмотреть изображение с полным размером)Figure 16: The Number of Days the Employee Has Been on the Job is Displayed (Click to view full-size image)

СводкаSummary

TemplateField в элементе управления GridView обеспечивает большую степень гибкости при отображении данных, чем доступно в других элементах управления "поле".The TemplateField in the GridView control allows for a higher degree of flexibility in displaying data than is available with the other field controls. Полей TemplateField идеально подходят для ситуаций, в которых:TemplateFields are ideal for situations where:

  • Несколько полей данных должны отображаться в одном столбце GridViewMultiple data fields need to be displayed in one GridView column
  • Данные лучше всего выражаются с помощью веб-элемента управления, а не обычного текста.The data is best expressed using a Web control rather than plain text
  • Выходные данные зависят от базовых данных, таких как отображение метаданных или переформатирование данных.The output depends on the underlying data, such as displaying metadata or in reformatting the data

Помимо настройки представления данных, полей TemplateField также используются для настройки пользовательских интерфейсов, используемых для редактирования и вставки данных, как мы увидим в следующих руководствах.In addition to customizing the display of data, TemplateFields are also used for customizing the user interfaces used for editing and inserting data, as we'll see in future tutorials.

Следующие два руководства продолжают изучать шаблоны, начиная с рассмотрения использования полей TemplateField в DetailsView.The next two tutorials continue exploring templates, starting with a look at using TemplateFields in a DetailsView. После этого мы вернемся к элементу FormView, который использует шаблоны вместо полей для обеспечения большей гибкости макета и структуры данных.Following that, we'll turn to the FormView, which uses templates in lieu of fields to provide greater flexibility in the layout and structure of the data.

Поздравляем с программированием!Happy Programming!

Об автореAbout the Author

Скотт Митчелл, автор семи книг по ASP/ASP. NET и основатель 4GuysFromRolla.com, работал с веб-технологиями Майкрософт с 1998.Scott Mitchell, author of seven ASP/ASP.NET books and founder of 4GuysFromRolla.com, has been working with Microsoft Web technologies since 1998. Скотт работает как независимый консультант, преподаватель и модуль записи.Scott works as an independent consultant, trainer, and writer. Его последняя книга — Sams обучать себя ASP.NET 2,0 за 24 часа.His latest book is Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Он доступен по адресу mitchell@4GuysFromRolla.com.He can be reached at mitchell@4GuysFromRolla.com. или через его блог, который можно найти по адресу http://ScottOnWriting.NET.or via his blog, which can be found at http://ScottOnWriting.NET.

Специальная благодарностьSpecial Thanks To

Эта серия руководств была рассмотрена многими полезными рецензентами.This tutorial series was reviewed by many helpful reviewers. Специалист по интересу для этого руководства был «Jagers)».Lead reviewer for this tutorial was Dan Jagers. Хотите ознакомиться с моими будущими статьями MSDN?Interested in reviewing my upcoming MSDN articles? Если это так, расположите строку в mitchell@4GuysFromRolla.com.If so, drop me a line at mitchell@4GuysFromRolla.com.