ASP.NET 2.0. Обзор новых сервисов, элементов управления и средств (1 часть)

Спустя четыре года после своего выхода ASP.NET стала «золотым стандартом» для Web-приложений, выполняемых на серверах под управлением Windows, а строка runat=»server» прочно вошла в лексикон Web-разработчиков всего мира. Кроме того, ASP.NET позволила очертить контуры будущего Web-программирования — будущего, в котором важное место занимают серверные элементы управления, выполняющие рендеринг HTML-кода и сценариев и вызывающие события. В следующей версии Microsoft .NET Framework ASP.NET 2.0 выйдет из подросткового возраста и станет зрелой платформой. Ее разработчики рассчитывают сократить на 70% и более объем кода, необходимого для решения типичных задач Web-программирования. Добиться этого нелегко, но возможно, поскольку благодаря многочисленным новым сервисам, элементам управления и средствам у ASP.NET 2.0 есть все шансы стать столь же значительным усовершенствованием ASP.NET 1.x, каким ASP.NET 1.x была для ASP. Эта статья — развернутый обзор новшеств в ASP.NET 2.0. Чтобы лучше осветить ключевые средства, я рассмотрю некоторые области более подробно и приведу примеры программ. Все примеры кода скомпилированы и протестированы в версии ASP.NET 2.0, предшествовавшей бета-версии. Возможно, чтобы эти примеры работали в бета-версии, некоторые из них придется изменить.

Эта статья написана на основе предварительной версии ASP.NET 2.0 Community Technology Preview, вышедшей в марте 2004 г. Любая содержащаяся здесь информация может быть изменена.Community Technology Preview, вышедшей в марте 2004 г. Любая содержащаяся здесь информация может быть изменена.

В статье используются следующие технологии: ASP.NET 1.x и C#.

В статье рассматриваются:

  • новые элементы управления, работающие с данными;
  • администрирование и роли;
  • персонализация и темы;
  • написание кода и параметры компиляции.

Master Pages

Один из самых бросающихся в глаза недостатков ASP.NET 1.x — отсутствие поддержки шаблонов страниц. Нельзя определить «эталонную страницу» (master page), от которой наследуют другие страницы. Разработчики решают эту проблему, создавая страницы с помощью пользовательских элементов управления, которые легко воспроизводить на разных страницах. В ASP.NET 2.0 больше не нужно прибегать к таким приемам, поскольку появилось новое средство — Master Pages. Чтобы описать, что такое Master Pages, подойдет термин «визуальное наследование». Сначала вы определяете эталонную страницу, содержащую то, что должно присутствовать на других страницах, и с помощью элементов управления ContentPlaceHolder задаете места, в которые дочерние страницы (subpages) могут помещать свое содержимое. Затем разрабатываете дочерние страницы — ASPX-файлы, ссылающиеся на эталонную страницу через директивы вида:

<%@ Page MasterPageFile="~/Foo.master" %>

В дочерних страницах с помощью элементов управления Content вы заполняете поля подстановки эталонной страницы. Открыв дочернюю страницу в браузере, вы увидите объединенное содержимое эталонной и дочерней страниц.

В приложении в листингах и эталонная страница используется, чтобы определить заголовок и колонтитул, показываемые на каждой странице. Дочерняя страница вставляет содержимое между заголовком и колонтитулом, добавляя элемент Content, ссылающийся на ContentPlaceHolder эталонной страницы. Обратите внимание на совпадение ID и ContentPlaceHolderID и на директиву @ Master в эталонной странице.

Листинг 1. Master Pages. Файл Master.master

<%@ Master %>

<html>
  <body leftmargin="0" topmargin="0" rightmargin="0"
    bottommargin="0" marginheight="0" marginwidth="0">
    <!-- Баннер -->
    <table cellspacing="0" cellpadding="0"
      style="background-image: url('/images/stripes.gif');
      background-repeat: repeat-x, repeat-y" width="100%">
      <tr><td align="center">
        <span style="font-family: verdana; font-size: 36pt;
          font-weight: bold; color: white">Master Pages</span><br>
        <span style="font-family: verdana; font-size: 10pt;
          font-weight: normal; color: white">Баннер определен
          в Master.master</span>
      </td></tr>
    </table>

    <!-- Поле подстановки для контента,
         помещаемого между баннером и колонтитулом -->
      <asp:ContentPlaceHolder ID="Main" RunAt="server" />
    </form>

    <!-- Колонтитул -->
    <table width="100%"><tr><td align="center">
      <span style="font-family: verdana; font-size: 8pt; color: red">
        Copyright (c) 2004 by Me Inc. Все права защищены<br>
        Колонтитул определен в Master.master
      </span>
    </td></tr></table>
  </body>
</html>

Листинг 2. Master Pages. Файл Subpage.aspx

<%@ Page MasterPageFile="~/Master.master" %>

<asp:Content ContentPlaceHolderID="Main" RunAt="server">
  <table width="100%" height="256px"><tr><td align="center">
    <h2>Содержимое определено в Subpage.aspx</h2>
  </td></tr></table>
</asp:Content>

Master Pages полностью поддерживается объектной моделью ASP.NET. В класс System.Web.UI.Page добавлено свойство Master, позволяющее дочерним страницам программно обращаться к своим эталонным страницам и определенным в них элементам управления. Допускается вложение эталонных страниц и включение в них контента по умолчанию, который могут переопределять дочерние страницы:

<asp:ContentPlaceHolder ID="Main" RunAt="server">
    Контент по умолчанию, показываемый в дочерних страницах,
    если он не переопределяется явным образом
</asp:ContentPlaceHolder>

Кроме того, в файле Web.config можно задать эталонную страницу, по умолчанию используемую приложением:

<configuration>
  <system.web>
    <pages masterPageFile="~/Foo.master" />
  </system.web>
</configuraion>

Разработчики дочерних страниц могут переопределять контент, используемый по умолчанию, и создавать собственные эталонные страницы. Изюминка Master Pages в том, что эта технология поддерживается Visual Studio 2005. При загрузке дочерней страницы IDE показывает содержимое, заданное в эталонной странице, блеклым цветом и не разрешает его изменять, а содержимое, заданное в дочерней странице, отображает обычными цветами и разрешает редактировать. Благодаря этому легко понять, где определено содержимое, и, если требуется отредактировать содержимое, относящееся к эталонной странице, вы просто открываете в IDE шаблон страницы.

Более полное описание Master Pages можно найти в статье Фрица Аньена (Fritz Onion), опубликованной в этом номере «MSDN Magazine».

Элементы управления — источники данных

Связывание с данными — замечательная возможность ASP.NET 1.x. Несколько строк кода для связывания с данными, помещенные в нужное место, заменяют массу ASP-кода, выполняющего запрос к базе данных и многократно вызывающего метод Response.Write, чтобы представить результаты запроса в HTML-формате. В ASP.NET 2.0 связывание с данными станет еще проще. Во многих случаях писать код вообще не потребуется благодаря новым элементам управления — источникам данных (элементам источников данных) (data source controls), перечисленным во врезке «Новые элементы управления, планируемые в ASP.NET 2.0″».

Следующая страница DataSource1.aspx, используя связывание с данными в ASP.NET 2.0, показывает выборку из базы данных Pubs (SQL Server):

<html>
  <body>
    <form runat="server">
      <asp:SqlDataSource ID="Titles" RunAt="server"
        ConnectionString="server=localhost;database=pubs;Integrated
                         Security=SSPI"
        SelectCommand="select title_id, title, price from titles" />
      <asp:DataGrid DataSourceID="Titles" RunAt="server" />
    </form>
  </body>
</html>

Элемент SqlDataSource определяет источник данных и выполняемый к нему запрос, а свойство DataSourceID элемента DataGrid ссылается на этот SqlDataSource. При загрузке страницы SqlDataSource выполняет запрос, результаты которого показываются в DataGrid.

Конечно, на практике связывание с данными редко бывает настолько простым. Допустим, вам нужно кэшировать результаты запроса или выполнять запросы к базам данных, указывая параметры, выбираемые в других элементах управления. Страница в листинге 3 использует один SqlDataSource, чтобы заполнить раскрывающийся список названиями стран из таблицы Customers базы данных Northwind, и другой — чтобы заполнить DataGrid перечнем клиентов из страны, выбранной в списке. Заметьте: элемент <SelectParameters> указывает, что SqlDataSource элемента управления DataGrid берет значение @country из раскрывающегося списка. Также обратите внимание на атрибуты EnableCaching и CacheDuration элемента SqlDataSource, связанного с выпадающим списком. Эти атрибуты указывают, что результаты запроса SELECT DISTINCT кэшируются в течение 60 секунд.

Табл. 1. Новые элементы управления, планируемые в ASP.NET 2.0
Простые элементы
BulletedList Показывает маркированный список элементов
FileUpload Позволяет закачивать файлы через Web-страницы
HiddenField Представляет скрытые поля (&lt;input type=&quot;hidden&quot;&gt;)
ImageMap Представляет карты изображений (image maps), используемые в HTML
Элементы источников данных
AccessDataSource Для связывания с данными баз Microsoft Access
ObjectDataSource Для связывания с данными классов, реализованных в собственных уровнях доступа к данным
SiteMapDataSource Для связывания с данными XML-карт сайта
SqlDataSource Для связывания с данными баз SQL, использующих провайдеры ADO.NET
XmlDataSource Для связывания с данными XML-документов
Элементы управления регистрацией
Login Интерфейс для входа с указанием имени пользователя и пароля
LoginName Отображает имена аутентифицированных пользователей
LoginStatus Интерфейс для входа и выхода
LoginView Показывает одно представление для пользователей, прошедших аутентификацию, и другое — для не прошедших
ChangePassword Интерфейс для смены паролей
PasswordRecovery Интерфейс для отправки забытых паролей по электронной почте
CreateUserWizard Интерфейс для создания новых учетных записей
Элементы управления страницами
Content Задает содержимое полей подстановки в страницах, наследуемых от Master Pages
DetailsView Отображает в HTML-таблице данные отдельной записи
DynamicImage Представляет динамически сгенерированные изображения
FormView Элемент, связываемый с данными, который поддерживает шаблоны и предоставляет очень гибкий UI
GridView Супер-DataGrid»; отображает наборы записей в виде HTML-таблиц
Menu Показывает выпадающие и восходящие (fly-out) меню
MultiView Разбивает страницу на несколько логических представлений
SiteMapPath Показывает пути к страницам
TreeView Представляет иерархические данные как деревья, узлы которых можно свертывать и развертывать
View Используется совместно с MultiView для определения индивидуальных представлений
Wizard Помогает пользователю пошагово выполнять определенные процедуры
Мобильные элементы управления
Pager Разбивает страницы на части для вывода на устройствах с небольшим экраном
PhoneLink Набирает телефонные номера на устройствах, оснащенных телефоном

Листинг 3. DataSource2.aspx

<html>
  <body>
    <form runat="server">
      <asp:SqlDataSource ID="Countries" RunAt="server"
        ConnectionString="server=localhost;database=northwind;
          Integrated Security=SSPI"
        SelectCommand="select distinct country from customers order by
                      country"
        EnableCaching="true" CacheDuration="60" />
      <asp:SqlDataSource ID="Customers" RunAt="server"
          ConnectionString="server=localhost;database=northwind;
            Integrated Security=SSPI"
          SelectCommand="select * from customers
            where country=@country">
        <SelectParameters>
          <asp:ControlParameter Name="Country"
            ControlID="MyDropDownList"
            PropertyName="SelectedValue" />
        </SelectParameters>
      </asp:SqlDataSource>
      <asp:DropDownList ID="MyDropDownList" DataSourceID="Countries"
        DataTextField="country" AutoPostBack="true" RunAt="server" />
      <asp:DataGrid DataSourceID="Customers" RunAt="server" />
    </form>
  </body>
</html>

Эти примеры — лишь малая часть возможностей, предоставляемых элементами источников данных. Например, можно вызывать хранимые процедуры, указывать в качестве параметров запросов значения, получаемые из строк запросов, ввода пользователя, состояния сеанса или cookie, а также задавать, что должен использовать элемент — DataSet или DataReader. Поскольку элементы источников данных обладают функциональностью адаптеров данных, с их помощью можно даже обновлять базы данных. Думаю, к моменту финального выпуска ASP.NET 2.0 появится много материалов, посвященных элементам источников данных. Дино Эспозито (Dino Esposito) рассматривает их значительно детальнее, чем я; см. рубрику «На переднем крае» в этом номере «MSDN Magazine».

Прежде чем закончить с темой связывания с данными, замечу, что ASP.NET 2.0 поддерживает упрощенный синтаксис связывания с данными. Разработчикам для ASP.NET приходится писать громоздкие выражения вида:

<%# DataBinder.Eval (Container.DataItem, "title") %>

В ASP.NET 2.0 это выражение можно заменить на:

<%# Eval("title") %>

Помимо оператора Eval ASP.NET 2.0 поддерживает операторы XPath и XPathSelect, которые через XPath-выражения определяют местонахождение данных в XML-документах.

ASP.NET-страницы могут оказаться довольно скучными, если не использовать атрибуты, придающие броский внешний вид элементам управления. Но сейчас есть одна проблема: атрибуты применяются по одному за раз и нельзя создавать «темы» элементов управления, т. е. сразу задавать значения группы визуальных атрибутов. Позвольте вас познакомить с темами и скинами — новым средством ASP.NET 2.0, облегчающим создание красиво оформленных страниц.

Чтобы увидеть, как работают темы и скины, добавьте в код DataSource2.aspx, показанный в листинге 3, сстроку:

<%@ Page Theme="BasicBlue" %>

Затем обновите страницу.

Теперь придадим странице совершенно другой вид. Добавим элемент и изменим директиву @ Page, указав другую тему:

<%@ Page Theme="SmokeAndGlass" %>

Новый атрибут Theme директивы @ Page объявляет, что к странице применяется заданная тема. Кроме того, темы можно применять программно через свойство Theme класса Page. Тема (theme) — это набор скинов, а скин (skin) — набор визуальных атрибутов, применяемых к типу элемента управления. BasicBlue и SmokeAndGlass — предопределенные, или глобальные, темы в ASP.NET 2.0. Их файлы содержатся в подкаталогах каталога Microsoft.NETFramework…ASP.NETClientFilesThemes.

Вы можете определить собственные темы и скины и развернуть их в подкаталогах каталога Themes вашего приложения. Каждый подкаталог содержит файлы определенной темы, причем имя темы совпадает с именем подкаталога. Подкаталог с темой содержит один или несколько .skin-файлов и другие ресурсы, используемые темой, например, файлы изображений и таблицы стилей. Определения скинов содержатся в .skin-файлах и во многом аналогичны тэгам, применяемым для объявления экземпляров элементов управления в ASPX-файлах.

Чтобы посмотреть, как это работает, создайте подкаталог Themes в папке, где находится DataSource2.aspx. В каталоге Themes создайте подкаталог ShockingPink. В каталоге ShockingPink создайте .skin-файл и поместите в него следующий фрагмент:

<asp:DropDownList runat="server" BackColor="hotpink"
  ForeColor="white" />

<asp:DataGrid runat="server" BackColor="#CCCCCC" BorderWidth="2pt"
  BorderStyle="Solid" BorderColor="#CCCCCC" GridLines="Vertical"
  HorizontalAlign="Left">
  <HeaderStyle ForeColor="white" BackColor="hotpink" />
  <ItemStyle ForeColor="black" BackColor="white" />
  <AlternatingItemStyle BackColor="pink" ForeColor="black" />
</asp:DataGrid>

Затем измените директиву @ Page в файле DataSource2.aspx:

<%@ Page Theme="ShockingPink" %>

В результате получится, несомненно, одна из самых кричащих Web-страниц, которые когда-либо создавались!

ShockingPink.skin задает внешний вид по умолчанию для элементов управления DropDownList и DataGrid. Имена .skin-файлов не обязательно должны совпадать с именами тем, к которым они относятся, хотя часто совпадают. Тема может содержать несколько .skin-файлов, а один .skin-файл может определять атрибуты для любого количества типов элементов управления. Кроме того, в ASP.NET бывают скины по умолчанию и не по умолчанию. Скин без атрибута SkinID по определению является скином по умолчанию. Скины не по умолчанию содержат атрибут SkinID, на который можно ссылаться, указывая SkinID в тэгах элементов управления.

Новые элементы управления

В ASP.NET 2.0 появится около 50 новых типов элементов управления, позволяющих разрабатывать богатый UI, не вникая в тонкости HTML, клиентских сценариев и DOM-модели (Document Object Model) браузера. На врезке «Новые элементы управления, планируемые в ASP.NET 2.0» перечислены элементы управления, которые на момент написания статьи предполагается ввести в ASP.NET 2.0 (в список не включены элементы Web Parts).

Элемент управления DynamicImage упрощает вывод на Web-страницах динамически генерируемых изображений. Раньше разработчикам приходилось писать для динамической генерации изображений собственные HTTP-обработчики или, что хуже, генерировать изображения в ASPX-файлах. Благодаря DynamicImage обе эти методики уходят в прошлое. DynamicImage в коде в листинге 4 используется, чтобы вывести круговую диаграмму. Ключевым является оператор, присваивающий биты изображения массиву ImageBytes элемента управления.

Листинг 4. DynamicImage.aspx

<%@ Import Namespace="System.Drawing" %>
<%@ Import Namespace="System.Drawing.Imaging" %>
<%@ Import Namespace="System.IO" %>

<html>
  <body>
    <asp:DynamicImage ID="PieChart" DynamicImageType="ImageBytes"
       RunAt="server" />
  </body>
</html>

<script language="C#" runat="server">
void Page_Load (Object sender, EventArgs e)
{
    // Создаем битовую карту и рисуем круговую диаграмму
    Bitmap bitmap = new Bitmap (240, 180, PixelFormat.Format32bppArgb);
    Graphics g = Graphics.FromImage (bitmap);
    DrawPieChart (g, Color.White, new decimal[]
        { 100.0m, 200.0m, 300.0m, 400.0m }, 240, 180);
    g.Dispose();

    // Присоединяем изображение к элементу DynamicImage
    MemoryStream stream = new MemoryStream ();
    bitmap.Save (stream, ImageFormat.Gif);
    bitmap.Dispose();
    PieChart.ImageBytes = stream.ToArray ();
}

void DrawPieChart (Graphics g, Color bkgnd, decimal[] vals,
    int width, int height)
{
    // Очищаем фон
    SolidBrush br = new SolidBrush (bkgnd);
    g.FillRectangle (br, 0, 0, width, height);
    br.Dispose ();

    // Создаем массив кистей
    SolidBrush[] brushes = new SolidBrush[6];
    brushes[0] = new SolidBrush (Color.Red);
    brushes[1] = new SolidBrush (Color.Yellow);
    brushes[2] = new SolidBrush (Color.Blue);
    brushes[3] = new SolidBrush (Color.Cyan);
    brushes[4] = new SolidBrush (Color.Magenta);
    brushes[5] = new SolidBrush (Color.Green);

    // Суммируем входные значения
    decimal total = 0.0m;
    foreach (decimal val in vals)
        total += val;

    // Рисуем диаграмму
    float start = 0.0f;
    float end = 0.0f;
    decimal current = 0.0m;

    for (int i=0; i<vals.Length; i++) {
        current += vals[i];
        start = end;
        end = (float) (current / total) * 360.0f;
        g.FillPie (brushes[i % 6], 0.0f, 0.0f, width, height,
            start, end - start);
    }

    // Очищаем ресурсы и выходим
    foreach (SolidBrush brush in brushes)
        brush.Dispose ();
}
</script>

Элемент управления DynamicImage использует новый сервис ASP.NET 2.0 — сервис генерации изображений. Этот сервис можно применять и при динамическом формировании изображений в ASIX-файлах (еще одно новшество ASP.NET 2.0). В примерах к этой статье (доступных на сайте MSDN Magazine) имеется файл DynamicImage.asix, демонстрирующий основы ASIX-файлов. Чтобы его запустить, скопируйте DynamicImage.asix в виртуальный каталог вашего Web-сервера и откройте в браузере.

Еще один интересный и потенциально очень полезный элемент управления, дебютирующий в ASP.NET 2.0, — MultiView. Элемент управления MultiView, используемый совместно с элементами управления View, служит для создания страниц с несколькими логическими представлениями. В любой момент показывается только одно представление (с индексом, равным значению свойства ActiveViewIndex элемента MultiView). Вы можете переходить от одного представления к другому, изменяя индекс активного представления. Элементы MultiView идеально подходят для страниц, где есть ярлычки или другие элементы управления, позволяющие выбирать текущую логическую страницу.

В странице в листинге 5 элемент MultiView используется, чтобы показать два разных представления таблицы Titles базы данных Pubs: одно выводится с помощью GridView, другое — с помощью DetailsView. Переключение между представлениями выполняется выбором элемента из раскрывающегося списка. Заметьте: атрибут AllowPaging тэга позволяет просматривать записи в DetailsView.

Листинг 5. MultiView.aspx

<%@ Page Theme="BasicBlue" %>

<html>
  <body>
    <form runat="server">
      <asp:SqlDataSource ID="Titles" RunAt="server"
        ConnectionString="server=localhost;database=pubs; Integrated
                          Security=SSPI"
        SelectCommand="select title_id, title, price from titles" />
      <asp:DropDownList ID="ViewType" AutoPostBack="true"
        OnSelectedIndexChanged="OnSwitchView" RunAt="server">
        <asp:ListItem Text="GridView" Selected="true" RunAt="server" />
        <asp:ListItem Text="DetailsView" RunAt="server" />
      </asp:DropDownList>
      <asp:MultiView ID="Main" ActiveViewIndex="0" RunAt="server">
        <asp:View RunAt="server">
          <asp:GridView DataSourceID="Titles" RunAt="server" />
        </asp:View>
        <asp:View RunAt="server">
          <asp:DetailsView DataSourceID="Titles" AllowPaging="true"
            RunAt="server" />
        </asp:View>
      </asp:MultiView>
    </form>
  </body>
</html>

<script language="C#" runat="server">
void Page_Load (Object sender, EventArgs e)
{
    if (IsPostBack)
        DataBind ();
}

void OnSwitchView (Object sender, EventArgs e)
{
    Main.ActiveViewIndex = ViewType.SelectedIndex;
}
</script>

Элементы управления GridView и DetailsView

DataGrid — один из самых популярных элементов управления в ASP.NET, но в некоторых отношениях он — жертва собственного успеха: у него настолько богатая функциональность, что разработчики для ASP.NET хотят еще большего. DataGrid в ASP.NET 2.0 изменился незначительно, зато появилось два новых элемента — GridView и DetailsView, предоставляющие возможности, которых часто требовали от DataGrid.

GridView, как и DataGrid, визуализирует HTML-таблицы, но в отличие от DataGrid может самостоятельно выполнять разбиение на страницы и сортировку. Кроме того, GridView поддерживает больше типов столбцов (типов полей в терминах GridView), чем DataGrid, и более интеллектуально ведет себя при рендеринге, например автоматически отображает логические значения флажками. Не составляет труда объединить GridView с DetailsView, чтобы создать представление «родитель-потомок». Основной недостаток GridView в том, что он, как и DataGrid, выполняет большую часть операций, возвращая форму на сервер.

В листинге 6 показано, как с помощью GridView и DetailsView создать простое представление «родитель-потомок» (master-detail view) таблицы Titles базы данных Pubs. Элементы SqlDataSource предоставляют данные, отображаемые этими элементами управления. SelectParameter элемента SqlDataSource связан с элементом GridView, что позволяет вывести в DetailsView запись, выбранную в GridView. Для выбора записи нужно щелкнуть одну из кнопок Select в элементе GridView. Чтобы такие кнопки появились, в тэг <asp:GridView> помещен атрибут AutoGenerateSelectButton=»true».

Листинг 6. MasterDetail.aspx

<%@ Page Theme="BasicBlue" %>

<html>
  <body>
    <form runat="server">
      <asp:SqlDataSource ID="Titles1" RunAt="server"
        ConnectionString="server=localhost;database=pubs;Integrated
          Security=SSPI"
        SelectCommand="select title_id, title, price from titles" />
      <asp:SqlDataSource ID="Titles2" RunAt="server"
        ConnectionString="server=localhost;database=pubs;Integrated
          Security=SSPI"
        SelectCommand="select title_id, title, price from titles where
          title_id=@title_id">
        <SelectParameters>
          <asp:ControlParameter Name="title_id" ControlID="MyGridView"
            PropertyName="SelectedValue" />
        </SelectParameters>
      </asp:SqlDataSource>
      <table><tr><td>
        <asp:GridView ID="MyGridView" DataSourceID="Titles1"
          Width="100%" RunAt="server" AutoGenerateColumns="false"
          SelectedIndex="0" AutoGenerateSelectButton="true"
          DataKeyNames="title_id">
          <Columns>
            <asp:BoundField HeaderText="Title ID"
              DataField="title_id" />
            <asp:BoundField HeaderText="Book Title"
              DataField="title" />
            <asp:BoundField HeaderText="Price" DataField="price"
              DataFormatString="{0:c}" NullDisplayText="TBD" />
          </Columns>
        </asp:GridView>
      </td></tr>
      <tr><td>
        <asp:DetailsView DataSourceID="Titles2" RunAt="server"
          AutoGenerateRows="false" Width="100%">
          <Fields>
            <asp:BoundField HeaderText="Title ID"
              DataField="title_id" />
            <asp:BoundField HeaderText="Book Title"
              DataField="title" />
            <asp:BoundField HeaderText="Price" DataField="price"
              DataFormatString="{0:c}" NullDisplayText="TBD" />
          </Fields>
        </asp:DetailsView>
      </td></tr></table>
    </form>
  </body>
</html>

Заметьте, что элементы <Columns> и <Fields> определяют типы полей элементов управления GridView и DetailsView. Они почти эквивалентны элементам <Columns> в элементах управления DataGrid. Поддерживаемые типы полей перечислены в табл. Особый интерес представляют типы ImageField и DropDownListField, избавляющие разработчиков от необходимости вручную писать код, который выводит в элементах управления DataGrid изображения и раскрывающиеся списки.

Табл. 2. Типы полей GridView и DetailsView
AutoGeneratedField Тип поля по умолчанию
BoundField Связывается с заданным полем источника данных
ButtonField Показывает кнопку, кнопку-изображение или кнопку-ссылку
CheckBoxField Показывает флажок
CommandField Показывает кнопки для выбора и редактирования элементов
DropDownListField Показывает раскрывающийся список
HyperLinkField Показывает гиперссылку
ImageField Показывает изображение
TemplateField Показывает содержимое, определяемое HTML-шаблонами